github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/mongo/collections.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package mongo
     5  
     6  import (
     7  	"time"
     8  
     9  	"gopkg.in/mgo.v2"
    10  )
    11  
    12  // CollectionFromName returns a named collection on the specified database,
    13  // initialised with a new session. Also returned is a close function which
    14  // must be called when the collection is no longer required.
    15  func CollectionFromName(db *mgo.Database, coll string) (Collection, func()) {
    16  	session := db.Session.Copy()
    17  	newColl := db.C(coll).With(session)
    18  	return WrapCollection(newColl), session.Close
    19  }
    20  
    21  // Collection imperfectly insulates clients from the capacity to write to
    22  // MongoDB. Query results can still be used to write; and the Writeable
    23  // method exposes the underlying *mgo.Collection when absolutely required;
    24  // but the general expectation in juju is that writes will occur only via
    25  // mgo/txn, and any layer-skipping is done only in exceptional and well-
    26  // supported circumstances.
    27  type Collection interface {
    28  
    29  	// Name returns the name of the collection.
    30  	Name() string
    31  
    32  	// Count, Find, and FindId methods act as documented for *mgo.Collection.
    33  	Count() (int, error)
    34  	Find(query interface{}) Query
    35  	FindId(id interface{}) Query
    36  
    37  	// Writeable gives access to methods that enable direct DB access. It
    38  	// should be used with judicious care, and for only the best of reasons.
    39  	Writeable() WriteCollection
    40  }
    41  
    42  // WriteCollection allows read/write access to a MongoDB collection.
    43  type WriteCollection interface {
    44  	Collection
    45  
    46  	// Underlying returns the underlying *mgo.Collection.
    47  	Underlying() *mgo.Collection
    48  
    49  	// All other methods act as documented for *mgo.Collection.
    50  	Insert(docs ...interface{}) error
    51  	Upsert(selector interface{}, update interface{}) (info *mgo.ChangeInfo, err error)
    52  	UpsertId(id interface{}, update interface{}) (info *mgo.ChangeInfo, err error)
    53  	Update(selector interface{}, update interface{}) error
    54  	UpdateId(id interface{}, update interface{}) error
    55  	Remove(sel interface{}) error
    56  	RemoveId(id interface{}) error
    57  	RemoveAll(sel interface{}) (*mgo.ChangeInfo, error)
    58  }
    59  
    60  // Query allows access to a portion of a MongoDB collection.
    61  type Query interface {
    62  	All(result interface{}) error
    63  	Apply(change mgo.Change, result interface{}) (info *mgo.ChangeInfo, err error)
    64  	Batch(n int) Query
    65  	Comment(comment string) Query
    66  	Count() (n int, err error)
    67  	Distinct(key string, result interface{}) error
    68  	Explain(result interface{}) error
    69  	For(result interface{}, f func() error) error
    70  	Hint(indexKey ...string) Query
    71  	Iter() *mgo.Iter
    72  	Limit(n int) Query
    73  	LogReplay() Query
    74  	MapReduce(job *mgo.MapReduce, result interface{}) (info *mgo.MapReduceInfo, err error)
    75  	One(result interface{}) (err error)
    76  	Prefetch(p float64) Query
    77  	Select(selector interface{}) Query
    78  	SetMaxScan(n int) Query
    79  	SetMaxTime(d time.Duration) Query
    80  	Skip(n int) Query
    81  	Snapshot() Query
    82  	Sort(fields ...string) Query
    83  	Tail(timeout time.Duration) *mgo.Iter
    84  }
    85  
    86  // WrapCollection returns a Collection that wraps the supplied *mgo.Collection.
    87  func WrapCollection(coll *mgo.Collection) Collection {
    88  	return collectionWrapper{coll}
    89  }
    90  
    91  // collectionWrapper wraps a *mgo.Collection and implements Collection and
    92  // WriteCollection.
    93  type collectionWrapper struct {
    94  	*mgo.Collection
    95  }
    96  
    97  // Name is part of the Collection interface.
    98  func (cw collectionWrapper) Name() string {
    99  	return cw.Collection.Name
   100  }
   101  
   102  // Find is part of the Collection interface.
   103  func (cw collectionWrapper) Find(query interface{}) Query {
   104  	return queryWrapper{cw.Collection.Find(query)}
   105  }
   106  
   107  // FindId is part of the Collection interface.
   108  func (cw collectionWrapper) FindId(id interface{}) Query {
   109  	return queryWrapper{cw.Collection.FindId(id)}
   110  }
   111  
   112  // Writeable is part of the Collection interface.
   113  func (cw collectionWrapper) Writeable() WriteCollection {
   114  	return cw
   115  }
   116  
   117  // Underlying is part of the WriteCollection interface.
   118  func (cw collectionWrapper) Underlying() *mgo.Collection {
   119  	return cw.Collection
   120  }
   121  
   122  type queryWrapper struct {
   123  	*mgo.Query
   124  }
   125  
   126  func (qw queryWrapper) Batch(n int) Query {
   127  	return queryWrapper{qw.Query.Batch(n)}
   128  }
   129  
   130  func (qw queryWrapper) Comment(comment string) Query {
   131  	return queryWrapper{qw.Query.Comment(comment)}
   132  }
   133  
   134  func (qw queryWrapper) Hint(indexKey ...string) Query {
   135  	return queryWrapper{qw.Query.Hint(indexKey...)}
   136  }
   137  
   138  func (qw queryWrapper) Limit(n int) Query {
   139  	return queryWrapper{qw.Query.Limit(n)}
   140  }
   141  
   142  func (qw queryWrapper) LogReplay() Query {
   143  	return queryWrapper{qw.Query.LogReplay()}
   144  }
   145  
   146  func (qw queryWrapper) Prefetch(p float64) Query {
   147  	return queryWrapper{qw.Query.Prefetch(p)}
   148  }
   149  
   150  func (qw queryWrapper) Select(selector interface{}) Query {
   151  	return queryWrapper{qw.Query.Select(selector)}
   152  }
   153  
   154  func (qw queryWrapper) SetMaxScan(n int) Query {
   155  	return queryWrapper{qw.Query.SetMaxScan(n)}
   156  }
   157  
   158  func (qw queryWrapper) SetMaxTime(d time.Duration) Query {
   159  	return queryWrapper{qw.Query.SetMaxTime(d)}
   160  }
   161  
   162  func (qw queryWrapper) Skip(n int) Query {
   163  	return queryWrapper{qw.Query.Skip(n)}
   164  }
   165  
   166  func (qw queryWrapper) Snapshot() Query {
   167  	return queryWrapper{qw.Query.Snapshot()}
   168  }
   169  
   170  func (qw queryWrapper) Sort(fields ...string) Query {
   171  	return queryWrapper{qw.Query.Sort(fields...)}
   172  }