|
@@ -0,0 +1,378 @@
|
|
|
+package mongodbutil
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "log"
|
|
|
+ "qfw/util"
|
|
|
+ "runtime"
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ . "gopkg.in/mgo.v2/bson"
|
|
|
+)
|
|
|
+
|
|
|
+//统计
|
|
|
+func (m *Pool) Count(c string, query interface{}) int {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ //log.Println("count:", m.Size, m.MongodbAddr, m.DB, sess, m.GetMgoConn(), m)
|
|
|
+ var n int = 0
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ var err error
|
|
|
+ n, err = coll.Find(ObjToM(query)).Count()
|
|
|
+ if nil != err {
|
|
|
+ log.Println("CountError", err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return n
|
|
|
+}
|
|
|
+
|
|
|
+//统计
|
|
|
+func (m *Pool) CountByErr(c string, query interface{}) (int, error) {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ //log.Println("count:", m.Size, m.MongodbAddr, m.DB, sess, m.GetMgoConn(), m)
|
|
|
+ var n int = 0
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ var err error
|
|
|
+ n, err = coll.Find(ObjToM(query)).Count()
|
|
|
+ if nil != err {
|
|
|
+ return 0, err
|
|
|
+ } else {
|
|
|
+ return n, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return n, errors.New("no sess")
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Pool) Update(c string, query interface{}, set interface{}, upsert bool, multi bool) bool {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ b := true
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ var err error
|
|
|
+ if upsert {
|
|
|
+ _, err = coll.Upsert(ObjToM(query), ObjToM(set))
|
|
|
+ } else {
|
|
|
+ if multi {
|
|
|
+ _, err = coll.UpdateAll(ObjToM(query), ObjToM(set))
|
|
|
+ } else {
|
|
|
+ err = coll.Update(ObjToM(query), ObjToM(set))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if nil != err {
|
|
|
+ log.Println("UpdateError", err)
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Pool) UpdateById(c string, id interface{}, set interface{}) bool {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ b := false
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ var q interface{}
|
|
|
+ if sid, ok := id.(string); ok {
|
|
|
+ q = M{"_id": util.StringTOBsonId(sid)}
|
|
|
+ } else {
|
|
|
+ q = M{"_id": id}
|
|
|
+ }
|
|
|
+ err := coll.Update(q, ObjToM(set))
|
|
|
+ if nil != err {
|
|
|
+ log.Println("UpdateByIdError", err)
|
|
|
+ b = false
|
|
|
+ } else {
|
|
|
+ b = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|
|
|
+
|
|
|
+//批量更新
|
|
|
+
|
|
|
+func (m *Pool) UpdateBulkAll(db, c string, doc ...[]map[string]interface{}) bool {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ b := true
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(db).C(c)
|
|
|
+ bulk := coll.Bulk()
|
|
|
+ for _, v := range doc {
|
|
|
+ if len(v) == 2 {
|
|
|
+ bulk.Update(v[0], v[1])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _, err := bulk.Run()
|
|
|
+ if nil != err {
|
|
|
+ log.Println("BulkError", err)
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Pool) UpdateBulk(c string, doc ...[]map[string]interface{}) bool {
|
|
|
+ return m.UpdateBulkAll(m.DB, c, doc...)
|
|
|
+}
|
|
|
+
|
|
|
+//批量更新
|
|
|
+func (m *Pool) UpSertBulk(c string, doc ...[]map[string]interface{}) bool {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ b := true
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ bulk := coll.Bulk()
|
|
|
+ for _, v := range doc {
|
|
|
+ if len(v) == 2 {
|
|
|
+ bulk.Upsert(v[0], v[1])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _, err := bulk.Run()
|
|
|
+ if nil != err {
|
|
|
+ log.Println("BulkUpsertError", err)
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|
|
|
+
|
|
|
+//批量插入
|
|
|
+func (m *Pool) SaveBulk(c string, doc ...map[string]interface{}) bool {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ b := true
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ bulk := coll.Bulk()
|
|
|
+ for _, v := range doc {
|
|
|
+ bulk.Insert(v)
|
|
|
+ }
|
|
|
+ _, err := bulk.Run()
|
|
|
+ if nil != err {
|
|
|
+ log.Println("BulkError", err)
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Pool) Save(c string, doc interface{}) string {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ obj := ObjToM(doc)
|
|
|
+ id := NewObjectId()
|
|
|
+ (*obj)["_id"] = id
|
|
|
+ err := coll.Insert(obj)
|
|
|
+ if nil != err {
|
|
|
+ log.Println("SaveError", err)
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ return (strings.Split(fmt.Sprintf("%s", id), `"`)[1])
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+//查询单条对象
|
|
|
+func (m *Pool) FindOne(c string, query interface{}) (*map[string]interface{}, bool) {
|
|
|
+ return m.FindOneByField(c, query, nil)
|
|
|
+}
|
|
|
+
|
|
|
+//查询单条对象
|
|
|
+func (m *Pool) FindOneByField(c string, query interface{}, fields interface{}) (*map[string]interface{}, bool) {
|
|
|
+ defer util.Catch()
|
|
|
+ res, ok := m.Find(c, query, nil, fields, true, -1, -1)
|
|
|
+ if nil != res && len(*res) > 0 {
|
|
|
+ return &((*res)[0]), ok
|
|
|
+ }
|
|
|
+ return nil, ok
|
|
|
+}
|
|
|
+
|
|
|
+//查询单条对象
|
|
|
+func (m *Pool) FindById(c string, query string, fields interface{}) (*map[string]interface{}, bool) {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ var res map[string]interface{}
|
|
|
+ b := false
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ res = make(map[string]interface{})
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ var err error
|
|
|
+ err = coll.FindId(ObjectIdHex(query)).Select(ObjToOth(fields)).One(&res)
|
|
|
+ if nil != err {
|
|
|
+ log.Println("FindByIdError", err,query)
|
|
|
+ }
|
|
|
+ b = true
|
|
|
+ }
|
|
|
+ return &res, b
|
|
|
+}
|
|
|
+
|
|
|
+//底层查询方法
|
|
|
+func (m *Pool) Find(c string, query interface{}, order interface{}, fields interface{}, single bool, start int, limit int) (*[]map[string]interface{}, bool) {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ var res []map[string]interface{}
|
|
|
+ b := false
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ res = make([]map[string]interface{}, 1)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ var err error
|
|
|
+ if single {
|
|
|
+ err = coll.Find(ObjToM(query)).Select(ObjToOth(fields)).Sort(ObjToArr(order)...).One(&res[0])
|
|
|
+ } else if start > -1 {
|
|
|
+ err = coll.Find(ObjToM(query)).Select(ObjToOth(fields)).Sort(ObjToArr(order)...).Skip(start).Limit(limit).All(&res)
|
|
|
+ } else {
|
|
|
+ err = coll.Find(ObjToM(query)).Select(ObjToOth(fields)).Sort(ObjToArr(order)...).All(&res)
|
|
|
+ }
|
|
|
+ if nil != err {
|
|
|
+ //log.Println("FindError", err)
|
|
|
+ }
|
|
|
+ b = true
|
|
|
+ }
|
|
|
+ return &res, b
|
|
|
+}
|
|
|
+
|
|
|
+//删除对象
|
|
|
+func (m *Pool) Del(c string, query interface{}) bool {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ b := false
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ _, err := coll.RemoveAll(ObjToM(query))
|
|
|
+ if nil != err {
|
|
|
+ log.Println("DelError", err)
|
|
|
+ b = false
|
|
|
+ } else {
|
|
|
+ b = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Pool) GetObjectId(str string) ObjectId {
|
|
|
+ return ObjectIdHex(str)
|
|
|
+}
|
|
|
+
|
|
|
+func ObjToOth(query interface{}) *M {
|
|
|
+ return ObjToMQ(query, false)
|
|
|
+}
|
|
|
+func ObjToM(query interface{}) *M {
|
|
|
+ return ObjToMQ(query, true)
|
|
|
+}
|
|
|
+
|
|
|
+//obj(string,M)转M,查询用到
|
|
|
+func ObjToMQ(query interface{}, isQuery bool) *M {
|
|
|
+ data := make(M)
|
|
|
+ defer func() {
|
|
|
+ if r := recover(); r != nil {
|
|
|
+ log.Println("[E]", r)
|
|
|
+ for skip := 1; ; skip++ {
|
|
|
+ _, file, line, ok := runtime.Caller(skip)
|
|
|
+ if !ok {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ go log.Printf("%v,%v\n", file, line)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ if s2, ok2 := query.(*map[string]interface{}); ok2 {
|
|
|
+ data = M(*s2)
|
|
|
+ } else if s3, ok3 := query.(*M); ok3 {
|
|
|
+ return s3
|
|
|
+ } else if s, ok := query.(string); ok {
|
|
|
+ json.Unmarshal([]byte(strings.Replace(s, "'", "\"", -1)), &data)
|
|
|
+ if ss, oks := data["_id"]; oks && isQuery {
|
|
|
+ switch ss.(type) {
|
|
|
+ case string:
|
|
|
+ data["_id"] = ObjectIdHex(ss.(string))
|
|
|
+ case map[string]interface{}:
|
|
|
+ tmp := ss.(map[string]interface{})
|
|
|
+ for k, v := range tmp {
|
|
|
+ tmp[k] = ObjectIdHex(v.(string))
|
|
|
+ }
|
|
|
+ data["_id"] = tmp
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ } else if s1, ok1 := query.(map[string]interface{}); ok1 {
|
|
|
+ data = s1
|
|
|
+ } else if s4, ok4 := query.(M); ok4 {
|
|
|
+ data = s4
|
|
|
+ } else {
|
|
|
+ data = nil
|
|
|
+ }
|
|
|
+ return &data
|
|
|
+}
|
|
|
+
|
|
|
+//对象转数组
|
|
|
+func ObjToArr(obj interface{}) []string {
|
|
|
+ if s, ok := obj.(string); ok {
|
|
|
+ if strings.ContainsAny(s, "{") {
|
|
|
+ //暂时简单支持此种写法
|
|
|
+ var temp = make(M)
|
|
|
+ var str = []string{}
|
|
|
+ json.Unmarshal([]byte(s), &temp)
|
|
|
+ for k, v := range temp {
|
|
|
+ m := util.IntAll(v)
|
|
|
+ if m > 0 {
|
|
|
+ str = append(str, k)
|
|
|
+ } else {
|
|
|
+ str = append(str, "-"+k)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return str
|
|
|
+ } else {
|
|
|
+ return strings.Split(s, ",")
|
|
|
+ }
|
|
|
+ } else if s1, ok1 := obj.([]string); ok1 {
|
|
|
+ return s1
|
|
|
+ } else {
|
|
|
+ return []string{}
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//删除表
|
|
|
+func (m *Pool) DelColl(c string) bool {
|
|
|
+ defer util.Catch()
|
|
|
+ sess := m.Get()
|
|
|
+ b := true
|
|
|
+ if sess != nil {
|
|
|
+ defer m.Close(sess)
|
|
|
+ coll := sess.DB(m.DB).C(c)
|
|
|
+ err := coll.DropCollection()
|
|
|
+ if err != nil {
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ b = false
|
|
|
+ }
|
|
|
+ return b
|
|
|
+}
|