github.com/Datadog/cnab-go@v0.3.3-beta1.0.20191007143216-bba4b7e723d0/utils/crud/mongodb.go (about)

     1  package crud
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strings"
     7  
     8  	"github.com/globalsign/mgo"
     9  )
    10  
    11  // MongoClaimsCollection is the name of the claims collection.
    12  const MongoClaimsCollection = "cnab_claims"
    13  
    14  type mongoDBStore struct {
    15  	session    *mgo.Session
    16  	collection *mgo.Collection
    17  	dbName     string
    18  }
    19  
    20  type doc struct {
    21  	Name string `json:"name"`
    22  	Data []byte `json:"data"`
    23  }
    24  
    25  // NewMongoDBStore creates a new storage engine that uses MongoDB
    26  //
    27  // The URL provided must point to a MongoDB server and database.
    28  func NewMongoDBStore(url string) (Store, error) {
    29  	session, err := mgo.Dial(url)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	dbn, err := parseDBName(url)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  
    39  	return &mongoDBStore{
    40  		session:    session,
    41  		collection: session.DB(dbn).C(MongoClaimsCollection),
    42  		dbName:     dbn,
    43  	}, nil
    44  }
    45  
    46  func (s *mongoDBStore) List() ([]string, error) {
    47  	var res []doc
    48  	if err := s.collection.Find(nil).All(&res); err != nil {
    49  		return []string{}, wrapErr(err)
    50  	}
    51  	buf := []string{}
    52  	for _, v := range res {
    53  		buf = append(buf, v.Name)
    54  	}
    55  	return buf, nil
    56  }
    57  
    58  func (s *mongoDBStore) Store(name string, data []byte) error {
    59  	return wrapErr(s.collection.Insert(doc{name, data}))
    60  }
    61  func (s *mongoDBStore) Read(name string) ([]byte, error) {
    62  	res := doc{}
    63  	if err := s.collection.Find(map[string]string{"name": name}).One(&res); err != nil {
    64  		if err == mgo.ErrNotFound {
    65  			return nil, ErrRecordDoesNotExist
    66  		}
    67  		return []byte{}, wrapErr(err)
    68  	}
    69  	return res.Data, nil
    70  }
    71  func (s *mongoDBStore) Delete(name string) error {
    72  	return wrapErr(s.collection.Remove(map[string]string{"name": name}))
    73  }
    74  
    75  func wrapErr(err error) error {
    76  	if err == nil {
    77  		return err
    78  	}
    79  	return fmt.Errorf("mongo storage error: %s", err)
    80  }
    81  
    82  func parseDBName(dialStr string) (string, error) {
    83  	u, err := url.Parse(dialStr)
    84  	if err != nil {
    85  		return "", err
    86  	}
    87  	if u.Path != "" {
    88  		return strings.TrimPrefix(u.Path, "/"), nil
    89  	}
    90  	// If this returns empty, then the driver is supposed to substitute in the
    91  	// default database.
    92  	return "", nil
    93  }