@@ -71,24 +71,47 @@ func (bs *Blobstore) Upload(node *node.Node, source string) error {
71
71
}
72
72
defer reader .Close ()
73
73
74
- _ , err = bs .client .PutObject (context .Background (), bs .bucket , bs .path (node ), reader , node .Blobsize , minio.PutObjectOptions {ContentType : "application/octet-stream" , SendContentMd5 : true })
74
+ _ , err = bs .client .PutObject (context .Background (), bs .bucket , bs .pathFromNode (node ), reader , node .Blobsize , minio.PutObjectOptions {ContentType : "application/octet-stream" , SendContentMd5 : true })
75
75
76
76
if err != nil {
77
- return errors .Wrapf (err , "could not store object '%s' into bucket '%s'" , bs .path (node ), bs .bucket )
77
+ return errors .Wrapf (err , "could not store object '%s' into bucket '%s'" , bs .pathFromNode (node ), bs .bucket )
78
78
}
79
79
return nil
80
80
}
81
81
82
+ func (bs * Blobstore ) StreamingUpload (ctx context.Context , spaceid , blobid string , offset , objectSize int64 , reader io.Reader , userMetadata map [string ]string ) error {
83
+ key := bs .path (spaceid , blobid )
84
+ if offset > 0 {
85
+ // write a part
86
+ key = fmt .Sprintf ("%s:%d-%d" , key , offset , offset + objectSize )
87
+ }
88
+ _ , err := bs .client .PutObject (ctx , bs .bucket , key , reader , objectSize , minio.PutObjectOptions {ContentType : "application/octet-stream" , SendContentMd5 : true , UserMetadata : userMetadata })
89
+
90
+ if err != nil {
91
+ return errors .Wrapf (err , "could not stream object '%s' into bucket '%s'" , key , bs .bucket )
92
+ }
93
+ return nil
94
+ }
95
+
96
+ func (bs * Blobstore ) StreamingDownload (ctx context.Context , spaceid , blobid string , offset , objectSize int64 ) (io.ReadCloser , error ) {
97
+ key := bs .path (spaceid , blobid )
98
+ if offset > 0 {
99
+ // read a part
100
+ key = fmt .Sprintf ("%s:%d-%d" , key , offset , offset + objectSize )
101
+ }
102
+ return bs .client .GetObject (ctx , bs .bucket , key , minio.GetObjectOptions {})
103
+ }
104
+
82
105
// Download retrieves a blob from the blobstore for reading
83
106
func (bs * Blobstore ) Download (node * node.Node ) (io.ReadCloser , error ) {
84
- reader , err := bs .client .GetObject (context .Background (), bs .bucket , bs .path (node ), minio.GetObjectOptions {})
107
+ reader , err := bs .client .GetObject (context .Background (), bs .bucket , bs .pathFromNode (node ), minio.GetObjectOptions {})
85
108
if err != nil {
86
- return nil , errors .Wrapf (err , "could not download object '%s' from bucket '%s'" , bs .path (node ), bs .bucket )
109
+ return nil , errors .Wrapf (err , "could not download object '%s' from bucket '%s'" , bs .pathFromNode (node ), bs .bucket )
87
110
}
88
111
89
112
stat , err := reader .Stat ()
90
113
if err != nil {
91
- return nil , errors .Wrapf (err , "blob path: %s" , bs .path (node ))
114
+ return nil , errors .Wrapf (err , "blob path: %s" , bs .pathFromNode (node ))
92
115
}
93
116
94
117
if node .Blobsize != stat .Size {
@@ -100,14 +123,18 @@ func (bs *Blobstore) Download(node *node.Node) (io.ReadCloser, error) {
100
123
101
124
// Delete deletes a blob from the blobstore
102
125
func (bs * Blobstore ) Delete (node * node.Node ) error {
103
- err := bs .client .RemoveObject (context .Background (), bs .bucket , bs .path (node ), minio.RemoveObjectOptions {})
126
+ err := bs .client .RemoveObject (context .Background (), bs .bucket , bs .pathFromNode (node ), minio.RemoveObjectOptions {})
104
127
if err != nil {
105
- return errors .Wrapf (err , "could not delete object '%s' from bucket '%s'" , bs .path (node ), bs .bucket )
128
+ return errors .Wrapf (err , "could not delete object '%s' from bucket '%s'" , bs .pathFromNode (node ), bs .bucket )
106
129
}
107
130
return nil
108
131
}
109
132
110
- func (bs * Blobstore ) path (node * node.Node ) string {
133
+ func (bs * Blobstore ) pathFromNode (node * node.Node ) string {
134
+ return bs .path (node .SpaceID , node .BlobID )
135
+ }
136
+
137
+ func (bs * Blobstore ) path (spaceid , blobid string ) string {
111
138
// https://aws.amazon.com/de/premiumsupport/knowledge-center/s3-prefix-nested-folders-difference/
112
139
// Prefixes are used to partion a bucket. A prefix is everything except the filename.
113
140
// For a file `BucketName/foo/bar/lorem.ipsum`, `BucketName/foo/bar/` is the prefix.
@@ -116,5 +143,5 @@ func (bs *Blobstore) path(node *node.Node) string {
116
143
//
117
144
// Since the spaceID is always the same for a space, we don't need to pathify that, because it would
118
145
// not yield any performance gains
119
- return filepath .Clean (filepath .Join (node . SpaceID , lookup .Pathify (node . BlobID , 4 , 2 )))
146
+ return filepath .Clean (filepath .Join (spaceid , lookup .Pathify (blobid , 4 , 2 )))
120
147
}
0 commit comments