github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/persistence.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "github.com/juju/errors" 8 jujutxn "github.com/juju/txn" 9 "gopkg.in/mgo.v2" 10 "gopkg.in/mgo.v2/txn" 11 12 "github.com/juju/juju/state/storage" 13 ) 14 15 // Persistence exposes persistence-layer functionality of State. 16 type Persistence interface { 17 // One populates doc with the document corresponding to the given 18 // ID. Missing documents result in errors.NotFound. 19 One(collName, id string, doc interface{}) error 20 21 // All populates docs with the list of the documents corresponding 22 // to the provided query. 23 All(collName string, query, docs interface{}) error 24 25 // Run runs the transaction generated by the provided factory 26 // function. It may be retried several times. 27 Run(transactions jujutxn.TransactionSource) error 28 29 // NewStorage returns a new blob storage for the environment. 30 NewStorage() storage.Storage 31 32 // ApplicationExistsOps returns the operations that verify that the 33 // identified application exists. 34 ApplicationExistsOps(applicationID string) []txn.Op 35 36 // IncCharmModifiedVersionOps returns the operations necessary to increment 37 // the CharmModifiedVersion field for the given application. 38 IncCharmModifiedVersionOps(applicationID string) []txn.Op 39 40 // NewCleanupOp creates a mgo transaction operation that queues up 41 // some cleanup action in state. 42 NewCleanupOp(kind, prefix string) txn.Op 43 } 44 45 type statePersistence struct { 46 st *State 47 } 48 49 // newPersistence builds a new StatePersistence that wraps State. 50 func (st *State) newPersistence() Persistence { 51 return &statePersistence{st: st} 52 } 53 54 // One gets the identified document from the collection. 55 func (sp statePersistence) One(collName, id string, doc interface{}) error { 56 coll, closeColl := sp.st.getCollection(collName) 57 defer closeColl() 58 59 err := coll.FindId(id).One(doc) 60 if err == mgo.ErrNotFound { 61 return errors.NotFoundf(id) 62 } 63 if err != nil { 64 return errors.Trace(err) 65 } 66 return nil 67 } 68 69 // All gets all documents from the collection matching the query. 70 func (sp statePersistence) All(collName string, query, docs interface{}) error { 71 coll, closeColl := sp.st.getCollection(collName) 72 defer closeColl() 73 74 if err := coll.Find(query).All(docs); err != nil { 75 return errors.Trace(err) 76 } 77 return nil 78 } 79 80 // Run runs the transaction produced by the provided factory function. 81 func (sp statePersistence) Run(transactions jujutxn.TransactionSource) error { 82 if err := sp.st.run(transactions); err != nil { 83 return errors.Trace(err) 84 } 85 return nil 86 } 87 88 // NewStorage returns a new blob storage for the environment. 89 func (sp *statePersistence) NewStorage() storage.Storage { 90 envUUID := sp.st.ModelUUID() 91 // TODO(ericsnow) Copy the session? 92 session := sp.st.session 93 store := storage.NewStorage(envUUID, session) 94 return store 95 } 96 97 // ApplicationExistsOps returns the operations that verify that the 98 // identified service exists. 99 func (sp *statePersistence) ApplicationExistsOps(applicationID string) []txn.Op { 100 return []txn.Op{{ 101 C: applicationsC, 102 Id: applicationID, 103 Assert: isAliveDoc, 104 }} 105 } 106 107 // IncCharmModifiedVersionOps returns the operations necessary to increment the 108 // CharmModifiedVersion field for the given service. 109 func (sp *statePersistence) IncCharmModifiedVersionOps(applicationID string) []txn.Op { 110 return incCharmModifiedVersionOps(applicationID) 111 } 112 113 // NewCleanupOp creates a mgo transaction operation that queues up 114 // some cleanup action in state. 115 func (sp *statePersistence) NewCleanupOp(kind, prefix string) txn.Op { 116 return newCleanupOp(cleanupKind(kind), prefix) 117 }