github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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 // ServiceExistsOps returns the operations that verify that the 33 // identified service exists. 34 ServiceExistsOps(serviceID string) []txn.Op 35 36 // IncCharmModifiedVersionOps returns the operations necessary to increment 37 // the CharmModifiedVersion field for the given service. 38 IncCharmModifiedVersionOps(serviceID 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 // ServiceExistsOps returns the operations that verify that the 98 // identified service exists. 99 func (sp *statePersistence) ServiceExistsOps(serviceID string) []txn.Op { 100 return []txn.Op{{ 101 C: servicesC, 102 Id: serviceID, 103 Assert: txn.DocExists, 104 }, { 105 C: servicesC, 106 Id: serviceID, 107 Assert: isAliveDoc, 108 }} 109 } 110 111 // IncCharmModifiedVersionOps returns the operations necessary to increment the 112 // CharmModifiedVersion field for the given service. 113 func (sp *statePersistence) IncCharmModifiedVersionOps(serviceID string) []txn.Op { 114 return incCharmModifiedVersionOps(serviceID) 115 } 116 117 // NewCleanupOp creates a mgo transaction operation that queues up 118 // some cleanup action in state. 119 func (sp *statePersistence) NewCleanupOp(kind, prefix string) txn.Op { 120 return sp.st.newCleanupOp(cleanupKind(kind), prefix) 121 }