func (gfc gridFileCacheable) ID() interface{} {
	return gfc.mf.Id()
}
implement `Identity` interface
package server
import (
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"log"
	"time"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)
type GridfsStorage struct {
	Connection *mgo.Session
}
type Storage interface {
	StoreChildImage(database, imageFormat string, imageData io.Reader, imageWidth, imageHeight int, original Cacheable, entry *Entry) (Cacheable, error)
	FindImageByParentID(namespace, id string, entry *Entry) (Cacheable, error)
	FindImageByParentFilename(namespace, filename string, entry *Entry) (Cacheable, error)
	IsValidID(id string) bool
}
func NewGridfsStorage(con *mgo.Session) (Storage, error) {
	if con == nil {
		return nil, errors.New("mgo.Session must be set")
	}
	return &GridfsStorage{Connection: con}, nil
}
type Cacheable interface {
	CacheIdentifier() string
	LastModified() time.Time
	Data() ReadSeekCloser
	Name() string
}
type ReadSeekCloser interface {
	io.ReadCloser
	io.Seeker
}
type MetaContainer interface {
	Meta() map[string]interface{}
}
type Identity interface {
	ID() interface{}
}
type gridFileCacheable struct {
	mf *mgo.GridFile
}
func (gfc gridFileCacheable) LastModified() time.Time {
	return gfc.mf.UploadDate()
}
func (gfc gridFileCacheable) CacheIdentifier() string {
	return gfc.mf.MD5()
}
func (gfc gridFileCacheable) Name() string {
	return gfc.mf.Name()
}
func (gfc gridFileCacheable) Data() ReadSeekCloser {
	return gfc.mf
}
func (gfc gridFileCacheable) Meta() map[string]interface{} {
	originalMetadata := bson.M{}
	if err := gfc.mf.GetMeta(&originalMetadata); err != nil {
		return map[string]interface{}{}
	}
	return originalMetadata
}