prefixedbucketstorage.go 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package storage
  2. // Partially forked from Thanos prefixed bucket for prefix handling
  3. // Licensed under the Apache License 2.0
  4. // https://github.com/thanos-io/objstore/blob/main/prefixed_bucket.go
  5. import (
  6. "fmt"
  7. "strings"
  8. "github.com/pkg/errors"
  9. )
  10. type PrefixedBucketStorage struct {
  11. storage Storage
  12. prefix string
  13. }
  14. func NewPrefixedBucketStorage(storage Storage, prefix string) (Storage, error) {
  15. if validPrefix(prefix) {
  16. return &PrefixedBucketStorage{
  17. storage: storage,
  18. prefix: strings.Trim(prefix, DirDelim),
  19. }, nil
  20. }
  21. return storage, errors.Errorf("failed to create prefixed storage: invalid prefix '%s'", prefix)
  22. }
  23. func validPrefix(prefix string) bool {
  24. prefix = strings.Replace(prefix, "/", "", -1)
  25. return len(prefix) > 0
  26. }
  27. func conditionalPrefix(prefix, name string) string {
  28. if len(name) > 0 && !strings.HasPrefix(name, prefix) {
  29. return withPrefix(prefix, name)
  30. }
  31. return name
  32. }
  33. func withPrefix(prefix, name string) string {
  34. return prefix + DirDelim + name
  35. }
  36. // String returns the string representation of the prefixed bucket storage.
  37. func (pbs *PrefixedBucketStorage) String() string {
  38. if stringer, ok := pbs.storage.(fmt.Stringer); ok {
  39. return stringer.String()
  40. }
  41. return ""
  42. }
  43. func (pbs *PrefixedBucketStorage) StorageType() StorageType {
  44. return pbs.storage.StorageType()
  45. }
  46. // FullPath returns the storage working path combined with the path provided.
  47. func (pbs *PrefixedBucketStorage) FullPath(name string) string {
  48. return pbs.storage.FullPath(conditionalPrefix(pbs.prefix, name))
  49. }
  50. // Exists checks if the given object exists.
  51. func (pbs *PrefixedBucketStorage) Exists(name string) (bool, error) {
  52. return pbs.storage.Exists(conditionalPrefix(pbs.prefix, name))
  53. }
  54. // List returns storage information for files on the provided path.
  55. func (pbs *PrefixedBucketStorage) List(path string) ([]*StorageInfo, error) {
  56. return pbs.storage.List(conditionalPrefix(pbs.prefix, path))
  57. }
  58. // ListDirectories returns storage information for only directories on the provided path.
  59. func (pbs *PrefixedBucketStorage) ListDirectories(path string) ([]*StorageInfo, error) {
  60. return pbs.storage.ListDirectories(conditionalPrefix(pbs.prefix, path))
  61. }
  62. // Read returns a reader for the given object name.
  63. func (pbs *PrefixedBucketStorage) Read(name string) ([]byte, error) {
  64. return pbs.storage.Read(conditionalPrefix(pbs.prefix, name))
  65. }
  66. // Remove deletes the object with the given name.
  67. func (pbs *PrefixedBucketStorage) Remove(name string) error {
  68. return pbs.storage.Remove(conditionalPrefix(pbs.prefix, name))
  69. }
  70. // Stat returns information about the specified object.
  71. func (pbs *PrefixedBucketStorage) Stat(name string) (*StorageInfo, error) {
  72. return pbs.storage.Stat(conditionalPrefix(pbs.prefix, name))
  73. }
  74. // Write uploads the contents of the reader as an object into the bucket.
  75. func (pbs *PrefixedBucketStorage) Write(name string, data []byte) error {
  76. return pbs.storage.Write(conditionalPrefix(pbs.prefix, name), data)
  77. }