/
gridfs.go
77 lines (65 loc) · 1.9 KB
/
gridfs.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
// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package blobstore
import (
"io"
"github.com/juju/errors"
"github.com/juju/loggo"
"gopkg.in/mgo.v2"
)
var logger = loggo.GetLogger("juju.storage")
type gridFSStorage struct {
dbName string
namespace string
session *mgo.Session
}
var _ ResourceStorage = (*gridFSStorage)(nil)
// NewGridFS returns a ResourceStorage instance backed by a mongo GridFS.
// namespace is used to segregate different sets of data.
func NewGridFS(dbName, namespace string, session *mgo.Session) ResourceStorage {
return &gridFSStorage{
dbName: dbName,
namespace: namespace,
session: session,
}
}
func (g *gridFSStorage) db() *mgo.Database {
return g.session.DB(g.dbName)
}
func (g *gridFSStorage) gridFS() *mgo.GridFS {
return g.db().GridFS(g.namespace)
}
// Get is defined on ResourceStorage.
func (g *gridFSStorage) Get(path string) (io.ReadCloser, error) {
file, err := g.gridFS().Open(path)
if err != nil {
return nil, errors.Annotatef(err, "failed to open GridFS file %q", path)
}
return file, nil
}
// Put is defined on ResourceStorage.
func (g *gridFSStorage) Put(path string, r io.Reader, length int64) (checksum string, err error) {
file, err := g.gridFS().Create(path)
if err != nil {
return "", errors.Annotatef(err, "failed to create GridFS file %q", path)
}
defer func() {
if err != nil {
file.Close()
if removeErr := g.Remove(path); removeErr != nil {
logger.Warningf("error cleaning up after failed write: %v", removeErr)
}
}
}()
if _, err = io.CopyN(file, r, length); err != nil {
return "", errors.Annotatef(err, "failed to write data")
}
if err = file.Close(); err != nil {
return "", errors.Annotatef(err, "failed to flush data")
}
return file.MD5(), nil
}
// Remove is defined on ResourceStorage.
func (g *gridFSStorage) Remove(path string) error {
return g.gridFS().Remove(path)
}