storage.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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(path string) ([]*StorageInfo, error)
  42. }
  43. // Validate uses the provided storage implementation to write a test file to the store, followed by a removal.
  44. func Validate(storage Storage) error {
  45. const testPath = "tmp/test.txt"
  46. const testContent = "test"
  47. // attempt to read a path
  48. _, err := storage.Exists(testPath)
  49. if err != nil {
  50. return errors.Wrap(err, "Failed to check if path exists")
  51. }
  52. // attempt to write a path
  53. err = storage.Write(testPath, []byte(testContent))
  54. if err != nil {
  55. return errors.Wrap(err, "Failed to write data to storage")
  56. }
  57. // attempt to read the path
  58. data, err := storage.Read(testPath)
  59. if err != nil {
  60. return errors.Wrap(err, "Failed to read data from storage")
  61. }
  62. if string(data) != testContent {
  63. return errors.New("Failed to read the expected data from storage")
  64. }
  65. // delete the path
  66. err = storage.Remove(testPath)
  67. if err != nil {
  68. return errors.Wrap(err, "Failed to remove data from storage")
  69. }
  70. return nil
  71. }
  72. // IsNotExist returns true if the error provided from a storage object is DoesNotExist
  73. func IsNotExist(err error) bool {
  74. if err == nil {
  75. return false
  76. }
  77. return err.Error() == DoesNotExistError.Error()
  78. }