~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/blobstore/gridfs.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2014 Canonical Ltd.
 
2
// Licensed under the LGPLv3, see LICENCE file for details.
 
3
 
 
4
package blobstore
 
5
 
 
6
import (
 
7
        "io"
 
8
 
 
9
        "github.com/juju/errors"
 
10
        "github.com/juju/loggo"
 
11
        "gopkg.in/mgo.v2"
 
12
)
 
13
 
 
14
var logger = loggo.GetLogger("juju.storage")
 
15
 
 
16
type gridFSStorage struct {
 
17
        dbName    string
 
18
        namespace string
 
19
        session   *mgo.Session
 
20
}
 
21
 
 
22
var _ ResourceStorage = (*gridFSStorage)(nil)
 
23
 
 
24
// NewGridFS returns a ResourceStorage instance backed by a mongo GridFS.
 
25
// namespace is used to segregate different sets of data.
 
26
func NewGridFS(dbName, namespace string, session *mgo.Session) ResourceStorage {
 
27
        return &gridFSStorage{
 
28
                dbName:    dbName,
 
29
                namespace: namespace,
 
30
                session:   session,
 
31
        }
 
32
}
 
33
 
 
34
func (g *gridFSStorage) db() *mgo.Database {
 
35
        return g.session.DB(g.dbName)
 
36
}
 
37
 
 
38
func (g *gridFSStorage) gridFS() *mgo.GridFS {
 
39
        return g.db().GridFS(g.namespace)
 
40
}
 
41
 
 
42
// Get is defined on ResourceStorage.
 
43
func (g *gridFSStorage) Get(path string) (io.ReadCloser, error) {
 
44
        file, err := g.gridFS().Open(path)
 
45
        if err != nil {
 
46
                return nil, errors.Annotatef(err, "failed to open GridFS file %q", path)
 
47
        }
 
48
        return file, nil
 
49
}
 
50
 
 
51
// Put is defined on ResourceStorage.
 
52
func (g *gridFSStorage) Put(path string, r io.Reader, length int64) (checksum string, err error) {
 
53
        file, err := g.gridFS().Create(path)
 
54
        if err != nil {
 
55
                return "", errors.Annotatef(err, "failed to create GridFS file %q", path)
 
56
        }
 
57
        defer func() {
 
58
                if err != nil {
 
59
                        file.Close()
 
60
                        if removeErr := g.Remove(path); removeErr != nil {
 
61
                                logger.Warningf("error cleaning up after failed write: %v", removeErr)
 
62
                        }
 
63
                }
 
64
        }()
 
65
        if _, err = io.CopyN(file, r, length); err != nil {
 
66
                return "", errors.Annotatef(err, "failed to write data")
 
67
        }
 
68
        if err = file.Close(); err != nil {
 
69
                return "", errors.Annotatef(err, "failed to flush data")
 
70
        }
 
71
        return file.MD5(), nil
 
72
}
 
73
 
 
74
// Remove is defined on ResourceStorage.
 
75
func (g *gridFSStorage) Remove(path string) error {
 
76
        return g.gridFS().Remove(path)
 
77
}