diff --git a/sysmodule/mangomodule/mongomodule.go b/sysmodule/mangomodule/mongomodule.go new file mode 100644 index 0000000..a12eaba --- /dev/null +++ b/sysmodule/mangomodule/mongomodule.go @@ -0,0 +1,129 @@ +package mangomodule + +import ( + "github.com/duanhf2012/origin/log" + "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" + "sync" + "time" + + _ "gopkg.in/mgo.v2" +) + +// session +type Session struct { + *mgo.Session +} + +type DialContext struct { + sync.Mutex + sessions []*Session + sessionNum uint32 + takeSessionIdx uint32 +} + +type MangoModule struct { + dailContext *DialContext +} + +func (slf *MangoModule) Init(url string,sessionNum uint32,dialTimeout time.Duration, timeout time.Duration) error { + var err error + slf.dailContext, err = dialWithTimeout(url, sessionNum, dialTimeout*time.Second, timeout*time.Minute) + + return err +} + + +func (slf *MangoModule) Take() *Session{ + return slf.dailContext.Take() +} + +// goroutine safe +func dialWithTimeout(url string, sessionNum uint32, dialTimeout time.Duration, timeout time.Duration) (*DialContext, error) { + if sessionNum <= 0 { + sessionNum = 100 + log.Release("invalid sessionNum, reset to %v", sessionNum) + } + + s, err := mgo.DialWithTimeout(url, dialTimeout) + if err != nil { + return nil, err + } + s.SetSyncTimeout(timeout) + s.SetSocketTimeout(timeout) + + c := new(DialContext) + + // sessions + c.sessions = make([]*Session, sessionNum) + c.sessions[0] = &Session{s} + for i:=uint32(1) ;i< sessionNum;i++{ + c.sessions[i] = &Session{s.New()} + } + + c.sessionNum = sessionNum + + return c, nil +} + +// goroutine safe +func (c *DialContext) Close() { + c.Lock() + for _, s := range c.sessions { + s.Close() + } + c.Unlock() +} + +func (c *DialContext) Take()*Session{ + c.Lock() + idx := c.takeSessionIdx %c.sessionNum + c.takeSessionIdx++ + c.Unlock() + + return c.sessions[idx] +} + +// goroutine safe +func (s *Session) EnsureCounter(db string, collection string, id string) error { + err := s.DB(db).C(collection).Insert(bson.M{ + "_id": id, + "seq": 0, + }) + if mgo.IsDup(err) { + return nil + } else { + return err + } +} + +// goroutine safe +func (s *Session) NextSeq(db string, collection string, id string) (int, error) { + var res struct { + Seq int + } + _, err := s.DB(db).C(collection).FindId(id).Apply(mgo.Change{ + Update: bson.M{"$inc": bson.M{"seq": 1}}, + ReturnNew: true, + }, &res) + + return res.Seq, err +} + +// goroutine safe +func (s *Session) EnsureIndex(db string, collection string, key []string) error { + return s.DB(db).C(collection).EnsureIndex(mgo.Index{ + Key: key, + Unique: false, + Sparse: true, + }) +} + +// goroutine safe +func (s *Session) EnsureUniqueIndex(db string, collection string, key []string) error { + return s.DB(db).C(collection).EnsureIndex(mgo.Index{ + Key: key, + Unique: true, + Sparse: true, + }) +} diff --git a/sysmodule/mangomodule/mongomodule_test.go b/sysmodule/mangomodule/mongomodule_test.go new file mode 100644 index 0000000..4f2251f --- /dev/null +++ b/sysmodule/mangomodule/mongomodule_test.go @@ -0,0 +1,75 @@ +package mangomodule + +import ( + "fmt" + _ "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" + "testing" + "time" +) + +type Student struct { + ID bson.ObjectId `bson:"_id"` + Name string `bson: "name"` + Age int `bson: "age"` + Sid string `bson: "sid"` + Status int `bson: "status"` +} + +func Test_Example(t *testing.T) { + module:=MangoModule{} + module.Init("127.0.0.1",100, 5*time.Second,5*time.Second) + + // take session + s := module.Take() + c := s.DB("test2").C("t_student") + + //2.定义对象 + insertData := Student{ + ID:bson.NewObjectId(), + Name: "seeta11", + Age: 35, //*^_^* + Sid: "s20180907", + Status: 1, + } + + updateData := Student{ + Name: "seeta11", + Age: 18, + Sid: "s20180907", + Status: 1, + } + + //3.插入数据 + err := c.Insert(&insertData) + + //4.查找数据 + selector := bson.M{"_id":bson.ObjectIdHex("5f25303e999c622d361989b0")} + m:=Student{} + err = c.Find(selector).One(&m) + + //5.更新数据 + //selector2 := bson.M{"_id":bson.ObjectIdHex("5f25303e999c622d361989b0")} + updateData.ID = bson.ObjectIdHex("5f25303e999c622d361989b0") + err = c.UpdateId(bson.ObjectIdHex("5f25303e999c622d361989b0"),&updateData) + if err != nil { + fmt.Print(err) + } + + //6.删除数据 + err = c.RemoveId(bson.ObjectIdHex("5f252f09999c622d36198951")) + if err != nil { + fmt.Print(err) + } + + //序号自增 + s.EnsureCounter("test2","t_student","5f252f09999c622d36198951") + for i := 0; i < 3; i++ { + id, err := s.NextSeq("test2", "t_student", "5f252f09999c622d36198951") + if err != nil { + fmt.Println(err) + return + } + fmt.Println(id) + } +}