/
lib.go
121 lines (103 loc) · 2.64 KB
/
lib.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package blobfs
import (
"bytes"
"context"
"io"
"path"
"strings"
"gocloud.dev/blob"
_ "gocloud.dev/blob/fileblob"
_ "gocloud.dev/blob/memblob"
)
type BlobFS struct {
storageURL string
prefix string
}
func New(storageURL string, prefix ...string) Interface {
prefix = append(prefix, "")
return &BlobFS{
storageURL: storageURL,
prefix: prefix[0],
}
}
func NewInMemoryFS() Interface {
return New("mem://")
}
func NewOsFs() Interface {
return New("file:///")
}
func (fs *BlobFS) WriteFile(ctx context.Context, filepath string, data []byte) error {
dir, filename := path.Split(filepath)
bucket, err := fs.openBucket(ctx, path.Join(fs.prefix, dir))
if err != nil {
return err
}
defer bucket.Close()
w, err := bucket.NewWriter(ctx, filename, nil)
if err != nil {
return err
}
_, writeErr := w.Write(data)
// Always check the return value of Close when writing.
closeErr := w.Close()
if writeErr != nil {
return writeErr
}
if closeErr != nil {
return closeErr
}
return nil
}
func (fs *BlobFS) ReadFile(ctx context.Context, filepath string) ([]byte, error) {
dir, filename := path.Split(filepath)
bucket, err := fs.openBucket(ctx, path.Join(fs.prefix, dir))
if err != nil {
return nil, err
}
defer bucket.Close()
// Open the key "foo.txt" for reading with the default options.
r, err := bucket.NewReader(ctx, filename, nil)
if err != nil {
return nil, err
}
defer r.Close()
var buf bytes.Buffer
if _, err := io.Copy(&buf, r); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (fs *BlobFS) DeleteFile(ctx context.Context, filepath string) error {
dir, filename := path.Split(filepath)
bucket, err := fs.openBucket(ctx, path.Join(fs.prefix, dir))
if err != nil {
return err
}
defer bucket.Close()
return bucket.Delete(context.TODO(), filename)
}
func (fs *BlobFS) Exists(ctx context.Context, filepath string) (bool, error) {
dir, filename := path.Split(filepath)
bucket, err := fs.openBucket(ctx, path.Join(fs.prefix, dir))
if err != nil {
return false, err
}
defer bucket.Close()
return bucket.Exists(context.TODO(), filename)
}
func (fs *BlobFS) SignedURL(ctx context.Context, filepath string, opts *blob.SignedURLOptions) (string, error) {
dir, filename := path.Split(filepath)
bucket, err := fs.openBucket(ctx, path.Join(fs.prefix, dir))
if err != nil {
return "", err
}
defer bucket.Close()
return bucket.SignedURL(ctx, filename, opts)
}
func (fs *BlobFS) openBucket(ctx context.Context, dir string) (*blob.Bucket, error) {
bucket, err := blob.OpenBucket(ctx, fs.storageURL)
if err != nil {
return nil, err
}
return blob.PrefixedBucket(bucket, strings.Trim(dir, "/")+"/"), nil
}