You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.1 KiB

  1. package filer
  2. import (
  3. "code.google.com/p/weed-fs/go/operation"
  4. "errors"
  5. "fmt"
  6. "path/filepath"
  7. "strings"
  8. )
  9. type FilerEmbedded struct {
  10. master string
  11. directories *DirectoryManagerInMap
  12. files *FileListInLevelDb
  13. }
  14. func NewFilerEmbedded(master string, dir string) (filer *FilerEmbedded, err error) {
  15. dm, de := NewDirectoryManagerInMap(filepath.Join(dir, "dir.log"))
  16. if de != nil {
  17. return nil, de
  18. }
  19. fl, fe := NewFileListInLevelDb(dir)
  20. if fe != nil {
  21. return nil, fe
  22. }
  23. filer = &FilerEmbedded{
  24. master: master,
  25. directories: dm,
  26. files: fl,
  27. }
  28. return
  29. }
  30. func (filer *FilerEmbedded) CreateFile(filePath string, fid string) (err error) {
  31. dir, file := filepath.Split(filePath)
  32. dirId, e := filer.directories.MakeDirectory(dir)
  33. if e != nil {
  34. return e
  35. }
  36. return filer.files.CreateFile(dirId, file, fid)
  37. }
  38. func (filer *FilerEmbedded) FindFile(filePath string) (fid string, err error) {
  39. dir, file := filepath.Split(filePath)
  40. dirId, e := filer.directories.FindDirectory(dir)
  41. if e != nil {
  42. return "", e
  43. }
  44. return filer.files.FindFile(dirId, file)
  45. }
  46. func (filer *FilerEmbedded) FindDirectory(dirPath string) (dirId DirectoryId, err error) {
  47. return filer.directories.FindDirectory(dirPath)
  48. }
  49. func (filer *FilerEmbedded) ListDirectories(dirPath string) (dirs []DirectoryEntry, err error) {
  50. return filer.directories.ListDirectories(dirPath)
  51. }
  52. func (filer *FilerEmbedded) ListFiles(dirPath string, lastFileName string, limit int) (files []FileEntry, err error) {
  53. dirId, e := filer.directories.FindDirectory(dirPath)
  54. if e != nil {
  55. return nil, e
  56. }
  57. return filer.files.ListFiles(dirId, lastFileName, limit), nil
  58. }
  59. func (filer *FilerEmbedded) DeleteDirectory(dirPath string, recursive bool) (err error) {
  60. dirId, e := filer.directories.FindDirectory(dirPath)
  61. if e != nil {
  62. return e
  63. }
  64. if sub_dirs, sub_err := filer.directories.ListDirectories(dirPath); sub_err == nil {
  65. if len(sub_dirs) > 0 && !recursive {
  66. return fmt.Errorf("Fail to delete directory %s: %d sub directories found!", dirPath, len(sub_dirs))
  67. }
  68. for _, sub := range sub_dirs {
  69. if delete_sub_err := filer.DeleteDirectory(filepath.Join(dirPath, sub.Name), recursive); delete_sub_err != nil {
  70. return delete_sub_err
  71. }
  72. }
  73. }
  74. list := filer.files.ListFiles(dirId, "", 100)
  75. if len(list) != 0 && !recursive {
  76. if !recursive {
  77. return fmt.Errorf("Fail to delete non-empty directory %s!", dirPath)
  78. }
  79. }
  80. for {
  81. if len(list) == 0 {
  82. return filer.directories.DeleteDirectory(dirPath)
  83. }
  84. var fids []string
  85. for _, fileEntry := range list {
  86. fids = append(fids, string(fileEntry.Id))
  87. }
  88. if result_list, delete_file_err := operation.DeleteFiles(filer.master, fids); delete_file_err != nil {
  89. return delete_file_err
  90. } else {
  91. if len(result_list.Errors) > 0 {
  92. return errors.New(strings.Join(result_list.Errors, "\n"))
  93. }
  94. }
  95. lastFile := list[len(list)-1]
  96. list = filer.files.ListFiles(dirId, lastFile.Name, 100)
  97. }
  98. }
  99. func (filer *FilerEmbedded) DeleteFile(filePath string) (fid string, err error) {
  100. dir, file := filepath.Split(filePath)
  101. dirId, e := filer.directories.FindDirectory(dir)
  102. if e != nil {
  103. return "", e
  104. }
  105. return filer.files.DeleteFile(dirId, file)
  106. }
  107. /*
  108. Move a folder or a file, with 4 Use cases:
  109. mv fromDir toNewDir
  110. mv fromDir toOldDir
  111. mv fromFile toDir
  112. mv fromFile toFile
  113. */
  114. func (filer *FilerEmbedded) Move(fromPath string, toPath string) error {
  115. if _, dir_err := filer.FindDirectory(fromPath); dir_err == nil {
  116. if _, err := filer.FindDirectory(toPath); err == nil {
  117. // move folder under an existing folder
  118. return filer.directories.MoveUnderDirectory(fromPath, toPath, "")
  119. } else {
  120. // move folder to a new folder
  121. return filer.directories.MoveUnderDirectory(fromPath, filepath.Dir(toPath), filepath.Base(toPath))
  122. }
  123. }
  124. if fid, file_err := filer.DeleteFile(fromPath); file_err == nil {
  125. if _, err := filer.FindDirectory(toPath); err == nil {
  126. // move file under an existing folder
  127. return filer.CreateFile(filepath.Join(toPath, filepath.Base(fromPath)), fid)
  128. } else {
  129. // move to a folder with new name
  130. return filer.CreateFile(toPath, fid)
  131. }
  132. }
  133. return fmt.Errorf("File %s is not found!", fromPath)
  134. }