storage.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package storage
  2. import (
  3. "os"
  4. "time"
  5. "github.com/pkg/errors"
  6. )
  7. // DirDelim is the delimiter used to model a directory structure in an object store bucket.
  8. const DirDelim = "/"
  9. // DoesNotExistError is used as a generic error to return when a target path does not
  10. // exist in storage. Equivalent to os.ErrorNotExist such that it will work with os.IsNotExist(err)
  11. var DoesNotExistError = os.ErrNotExist
  12. // StorageInfo is a data object containing basic information about the path in storage.
  13. type StorageInfo struct {
  14. Name string // base name of the file
  15. Size int64 // length in bytes for regular files
  16. ModTime time.Time // modification time
  17. }
  18. // Storage provides an API for storing binary data
  19. type Storage interface {
  20. // StorageType returns a string identifier for the type of storage used by the implementation.
  21. StorageType() StorageType
  22. // FullPath returns the storage working path combined with the path provided
  23. FullPath(path string) string
  24. // Stat returns the StorageStats for the specific path.
  25. Stat(path string) (*StorageInfo, error)
  26. // Read uses the relative path of the storage combined with the provided path to
  27. // read the contents.
  28. Read(path string) ([]byte, error)
  29. // Write uses the relative path of the storage combined with the provided path
  30. // to write a new file or overwrite an existing file.
  31. Write(path string, data []byte) error
  32. // Remove uses the relative path of the storage combined with the provided path to
  33. // remove a file from storage permanently.
  34. Remove(path string) error
  35. // Exists uses the relative path of the storage combined with the provided path to
  36. // determine if the file exists.
  37. Exists(path string) (bool, error)
  38. // List uses the relative path of the storage combined with the provided path to return
  39. // storage information for the files.
  40. List(path string) ([]*StorageInfo, error)
  41. // ListDirectories uses the relative path of the storage combined with the provided path
  42. // to return storage information for only directories contained along the path. This
  43. // functions as List, but returns storage information for only directories.
  44. ListDirectories(path string) ([]*StorageInfo, error)
  45. }
  46. // Validate uses the provided storage implementation to write a test file to the store, followed by a removal.
  47. func Validate(storage Storage) error {
  48. const testPath = "tmp/test.txt"
  49. const testContent = "test"
  50. // attempt to read a path
  51. _, err := storage.Exists(testPath)
  52. if err != nil {
  53. return errors.Wrap(err, "Failed to check if path exists")
  54. }
  55. // attempt to write a path
  56. err = storage.Write(testPath, []byte(testContent))
  57. if err != nil {
  58. return errors.Wrap(err, "Failed to write data to storage")
  59. }
  60. // attempt to read the path
  61. data, err := storage.Read(testPath)
  62. if err != nil {
  63. return errors.Wrap(err, "Failed to read data from storage")
  64. }
  65. if string(data) != testContent {
  66. return errors.New("Failed to read the expected data from storage")
  67. }
  68. // delete the path
  69. err = storage.Remove(testPath)
  70. if err != nil {
  71. return errors.Wrap(err, "Failed to remove data from storage")
  72. }
  73. return nil
  74. }
  75. // IsNotExist returns true if the error provided from a storage object is DoesNotExist
  76. func IsNotExist(err error) bool {
  77. if err == nil {
  78. return false
  79. }
  80. return err.Error() == DoesNotExistError.Error()
  81. }