github.com/lingyao2333/mo-zero@v1.4.1/core/stores/mongo/model.go (about) 1 package mongo 2 3 import ( 4 "log" 5 "time" 6 7 "github.com/globalsign/mgo" 8 "github.com/lingyao2333/mo-zero/core/breaker" 9 ) 10 11 // A Model is a mongo model. 12 type Model struct { 13 session *concurrentSession 14 db *mgo.Database 15 collection string 16 brk breaker.Breaker 17 opts []Option 18 } 19 20 // MustNewModel returns a Model, exits on errors. 21 func MustNewModel(url, collection string, opts ...Option) *Model { 22 model, err := NewModel(url, collection, opts...) 23 if err != nil { 24 log.Fatal(err) 25 } 26 27 return model 28 } 29 30 // NewModel returns a Model. 31 func NewModel(url, collection string, opts ...Option) (*Model, error) { 32 session, err := getConcurrentSession(url) 33 if err != nil { 34 return nil, err 35 } 36 37 return &Model{ 38 session: session, 39 // If name is empty, the database name provided in the dialed URL is used instead 40 db: session.DB(""), 41 collection: collection, 42 brk: breaker.GetBreaker(url), 43 opts: opts, 44 }, nil 45 } 46 47 // Find finds a record with given query. 48 func (mm *Model) Find(query interface{}) (Query, error) { 49 return mm.query(func(c Collection) Query { 50 return c.Find(query) 51 }) 52 } 53 54 // FindId finds a record with given id. 55 func (mm *Model) FindId(id interface{}) (Query, error) { 56 return mm.query(func(c Collection) Query { 57 return c.FindId(id) 58 }) 59 } 60 61 // GetCollection returns a Collection with given session. 62 func (mm *Model) GetCollection(session *mgo.Session) Collection { 63 return newCollection(mm.db.C(mm.collection).With(session), mm.brk) 64 } 65 66 // Insert inserts docs into mm. 67 func (mm *Model) Insert(docs ...interface{}) error { 68 return mm.execute(func(c Collection) error { 69 return c.Insert(docs...) 70 }) 71 } 72 73 // Pipe returns a Pipe with given pipeline. 74 func (mm *Model) Pipe(pipeline interface{}) (Pipe, error) { 75 return mm.pipe(func(c Collection) Pipe { 76 return c.Pipe(pipeline) 77 }) 78 } 79 80 // PutSession returns the given session. 81 func (mm *Model) PutSession(session *mgo.Session) { 82 mm.session.putSession(session) 83 } 84 85 // Remove removes the records with given selector. 86 func (mm *Model) Remove(selector interface{}) error { 87 return mm.execute(func(c Collection) error { 88 return c.Remove(selector) 89 }) 90 } 91 92 // RemoveAll removes all with given selector and returns a mgo.ChangeInfo. 93 func (mm *Model) RemoveAll(selector interface{}) (*mgo.ChangeInfo, error) { 94 return mm.change(func(c Collection) (*mgo.ChangeInfo, error) { 95 return c.RemoveAll(selector) 96 }) 97 } 98 99 // RemoveId removes a record with given id. 100 func (mm *Model) RemoveId(id interface{}) error { 101 return mm.execute(func(c Collection) error { 102 return c.RemoveId(id) 103 }) 104 } 105 106 // TakeSession gets a session. 107 func (mm *Model) TakeSession() (*mgo.Session, error) { 108 return mm.session.takeSession(mm.opts...) 109 } 110 111 // Update updates a record with given selector. 112 func (mm *Model) Update(selector, update interface{}) error { 113 return mm.execute(func(c Collection) error { 114 return c.Update(selector, update) 115 }) 116 } 117 118 // UpdateId updates a record with given id. 119 func (mm *Model) UpdateId(id, update interface{}) error { 120 return mm.execute(func(c Collection) error { 121 return c.UpdateId(id, update) 122 }) 123 } 124 125 // Upsert upserts a record with given selector, and returns a mgo.ChangeInfo. 126 func (mm *Model) Upsert(selector, update interface{}) (*mgo.ChangeInfo, error) { 127 return mm.change(func(c Collection) (*mgo.ChangeInfo, error) { 128 return c.Upsert(selector, update) 129 }) 130 } 131 132 func (mm *Model) change(fn func(c Collection) (*mgo.ChangeInfo, error)) (*mgo.ChangeInfo, error) { 133 session, err := mm.TakeSession() 134 if err != nil { 135 return nil, err 136 } 137 defer mm.PutSession(session) 138 139 return fn(mm.GetCollection(session)) 140 } 141 142 func (mm *Model) execute(fn func(c Collection) error) error { 143 session, err := mm.TakeSession() 144 if err != nil { 145 return err 146 } 147 defer mm.PutSession(session) 148 149 return fn(mm.GetCollection(session)) 150 } 151 152 func (mm *Model) pipe(fn func(c Collection) Pipe) (Pipe, error) { 153 session, err := mm.TakeSession() 154 if err != nil { 155 return nil, err 156 } 157 defer mm.PutSession(session) 158 159 return fn(mm.GetCollection(session)), nil 160 } 161 162 func (mm *Model) query(fn func(c Collection) Query) (Query, error) { 163 session, err := mm.TakeSession() 164 if err != nil { 165 return nil, err 166 } 167 defer mm.PutSession(session) 168 169 return fn(mm.GetCollection(session)), nil 170 } 171 172 // WithTimeout customizes an operation with given timeout. 173 func WithTimeout(timeout time.Duration) Option { 174 return func(opts *options) { 175 opts.timeout = timeout 176 } 177 }