package repo import ( "errors" "fmt" "time" "git.icod.de/dalu/refdata/model" "github.com/globalsign/mgo" "github.com/globalsign/mgo/bson" ) // type DataIdQuery struct { Id string } // string type DataNameQuery struct { Operation string Query string Options string } // string type DataAddressQuery struct { Operation string Query string Options string } // string type DataLocationQuery struct { Operation string Query string Options string } // int type DataAgeQuery struct { Operation string From int64 To int64 } // float64 type DataPriceQuery struct { Operation string From float64 To float64 } // bool type DataEnabledQuery struct { Query bool } // refid type DataRefIdQuery struct { Query string } // time type DataWhenQuery struct { Operation string From time.Time To time.Time } type DataParams struct { Start int // list only Limit int // list only Sort string // list only Id bool // get only Name bool Address bool Location bool Age bool Price bool Enabled bool When bool IdQuery DataIdQuery // get only NameQuery DataNameQuery AddressQuery DataAddressQuery LocationQuery DataLocationQuery AgeQuery DataAgeQuery PriceQuery DataPriceQuery EnabledQuery DataEnabledQuery WhenQuery DataWhenQuery } type DataRepository struct { ms *mgo.Session database string collection string } func NewDataRepository(ms *mgo.Session, db, c string) *DataRepository { r := new(DataRepository) r.ms = ms.Clone() r.database = db r.collection = c return r } func (r *DataRepository) Close() { r.ms.Close() } func (r *DataRepository) Count(p *DataParams) (int, error) { ms := r.ms.Copy() defer ms.Close() c := ms.DB(r.database).C(r.collection) q := bson.M{} // string if p.Name { switch p.NameQuery.Operation { case "eq": q["name"] = p.NameQuery.Query case "regex": q["name"] = bson.RegEx{Pattern: p.NameQuery.Query, Options: p.NameQuery.Options} } } // string if p.Address { switch p.AddressQuery.Operation { case "eq": q["address"] = p.AddressQuery.Query case "regex": q["address"] = bson.RegEx{Pattern: p.AddressQuery.Query, Options: p.AddressQuery.Options} } } // string if p.Location { switch p.LocationQuery.Operation { case "eq": q["address"] = p.LocationQuery.Query case "regex": q["address"] = bson.RegEx{Pattern: p.LocationQuery.Query, Options: p.LocationQuery.Options} } } // int64 if p.Age { switch p.AgeQuery.Operation { case "eq": q["age"] = p.AgeQuery.From case "gt-lt": q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lt": p.AgeQuery.To} case "gte-lte": q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lte": p.AgeQuery.To} case "gte-lt": q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lt": p.AgeQuery.To} case "gt-lte": q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lte": p.AgeQuery.To} case "gt": q["age"] = bson.M{"$gt": p.AgeQuery.From} case "gte": q["age"] = bson.M{"$gte": p.AgeQuery.From} case "lt": q["age"] = bson.M{"$lt": p.AgeQuery.To} case "lte": q["age"] = bson.M{"$lte": p.AgeQuery.To} } } // float64 if p.Price { switch p.PriceQuery.Operation { case "eq": q["price"] = p.PriceQuery.From case "gt": q["price"] = bson.M{"$gt": p.PriceQuery.From} case "gte": q["price"] = bson.M{"$gte": p.PriceQuery.From} case "lt": q["price"] = bson.M{"$lt": p.PriceQuery.To} case "lte": q["price"] = bson.M{"$lte": p.PriceQuery.To} case "gt-lt": q["price"] = bson.M{"$gt": p.PriceQuery.From, "$lt": p.PriceQuery.To} case "gte-lte": q["price"] = bson.M{"$gte": p.PriceQuery.From, "$lte": p.PriceQuery.To} case "gte-lt": q["price"] = bson.M{"$gte": p.PriceQuery.From, "$lt": p.PriceQuery.To} case "gt-lte": q["price"] = bson.M{"$gt": p.PriceQuery.From, "$lte": p.PriceQuery.To} } } // bool if p.Enabled { q["enabled"] = p.EnabledQuery.Query } // time if p.When { switch p.WhenQuery.Operation { case "eq": q["when"] = p.WhenQuery.From case "gt": q["when"] = bson.M{"$gt": p.WhenQuery.From} case "gte": q["when"] = bson.M{"$gte": p.WhenQuery.From} case "lt": q["when"] = bson.M{"$lt": p.WhenQuery.To} case "lte": q["when"] = bson.M{"$lte": p.WhenQuery.To} case "gt-lt": q["when"] = bson.M{"$gt": p.WhenQuery.From, "$lt": p.WhenQuery.To} case "gte-lte": q["when"] = bson.M{"$gte": p.WhenQuery.From, "$lte": p.WhenQuery.To} case "gte-lt": q["when"] = bson.M{"$gte": p.WhenQuery.From, "$lt": p.WhenQuery.To} case "gt-lte": q["when"] = bson.M{"$gt": p.WhenQuery.From, "$lte": p.WhenQuery.To} } } rq := c.Find(q) if p.Sort != "" { rq = rq.Sort(p.Sort) } if p.Start > 0 && p.Limit > 0 { rq = rq.Skip(p.Start).Limit(p.Limit) } else if p.Start > 0 && p.Limit < 1 { rq = rq.Skip(p.Start) } else if p.Start < 1 && p.Limit > 0 { rq = rq.Limit(p.Limit) } return rq.Count() } func (r *DataRepository) List(p *DataParams) ([]*model.Data, error) { ms := r.ms.Copy() defer ms.Close() c := ms.DB(r.database).C(r.collection) q := bson.M{} // string if p.Name { switch p.NameQuery.Operation { case "eq": q["name"] = p.NameQuery.Query case "regex": q["name"] = bson.RegEx{Pattern: p.NameQuery.Query, Options: p.NameQuery.Options} } } // string if p.Address { switch p.AddressQuery.Operation { case "eq": q["address"] = p.AddressQuery.Query case "regex": q["address"] = bson.RegEx{Pattern: p.AddressQuery.Query, Options: p.AddressQuery.Options} } } // string if p.Location { switch p.LocationQuery.Operation { case "eq": q["address"] = p.LocationQuery.Query case "regex": q["address"] = bson.RegEx{Pattern: p.LocationQuery.Query, Options: p.LocationQuery.Options} } } // int64 if p.Age { switch p.AgeQuery.Operation { case "eq": q["age"] = p.AgeQuery.From case "gt-lt": q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lt": p.AgeQuery.To} case "gte-lte": q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lte": p.AgeQuery.To} case "gte-lt": q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lt": p.AgeQuery.To} case "gt-lte": q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lte": p.AgeQuery.To} case "gt": q["age"] = bson.M{"$gt": p.AgeQuery.From} case "gte": q["age"] = bson.M{"$gte": p.AgeQuery.From} case "lt": q["age"] = bson.M{"$lt": p.AgeQuery.To} case "lte": q["age"] = bson.M{"$lte": p.AgeQuery.To} } } // float64 if p.Price { switch p.PriceQuery.Operation { case "eq": q["price"] = p.PriceQuery.From case "gt": q["price"] = bson.M{"$gt": p.PriceQuery.From} case "gte": q["price"] = bson.M{"$gte": p.PriceQuery.From} case "lt": q["price"] = bson.M{"$lt": p.PriceQuery.To} case "lte": q["price"] = bson.M{"$lte": p.PriceQuery.To} case "gt-lt": q["price"] = bson.M{"$gt": p.PriceQuery.From, "$lt": p.PriceQuery.To} case "gte-lte": q["price"] = bson.M{"$gte": p.PriceQuery.From, "$lte": p.PriceQuery.To} case "gte-lt": q["price"] = bson.M{"$gte": p.PriceQuery.From, "$lt": p.PriceQuery.To} case "gt-lte": q["price"] = bson.M{"$gt": p.PriceQuery.From, "$lte": p.PriceQuery.To} } } // bool if p.Enabled { q["enabled"] = p.EnabledQuery.Query } // time if p.When { switch p.WhenQuery.Operation { case "eq": q["when"] = p.WhenQuery.From case "gt": q["when"] = bson.M{"$gt": p.WhenQuery.From} case "gte": q["when"] = bson.M{"$gte": p.WhenQuery.From} case "lt": q["when"] = bson.M{"$lt": p.WhenQuery.To} case "lte": q["when"] = bson.M{"$lte": p.WhenQuery.To} case "gt-lt": q["when"] = bson.M{"$gt": p.WhenQuery.From, "$lt": p.WhenQuery.To} case "gte-lte": q["when"] = bson.M{"$gte": p.WhenQuery.From, "$lte": p.WhenQuery.To} case "gte-lt": q["when"] = bson.M{"$gte": p.WhenQuery.From, "$lt": p.WhenQuery.To} case "gt-lte": q["when"] = bson.M{"$gt": p.WhenQuery.From, "$lte": p.WhenQuery.To} } } var m []*model.Data rq := c.Find(q) if p.Sort != "" { rq = rq.Sort(p.Sort) } if p.Start > 0 && p.Limit > 0 { rq = rq.Skip(p.Start).Limit(p.Limit) } else if p.Start > 0 && p.Limit < 1 { rq = rq.Skip(p.Start) } else if p.Start < 1 && p.Limit > 0 { rq = rq.Limit(p.Limit) } if e := rq.All(&m); e != nil { return nil, e } return m, nil } func (r *DataRepository) Get(p *DataParams) (*model.Data, error) { ms := r.ms.Copy() defer ms.Close() c := ms.DB(r.database).C(r.collection) q := bson.M{} // id if p.Id { q["_id"] = bson.ObjectIdHex(p.IdQuery.Id) } // string if p.Name { switch p.NameQuery.Operation { case "eq": q["name"] = p.NameQuery.Query case "regex": q["name"] = bson.RegEx{Pattern: p.NameQuery.Query, Options: p.NameQuery.Options} } } // string if p.Address { switch p.AddressQuery.Operation { case "eq": q["address"] = p.AddressQuery.Query case "regex": q["address"] = bson.RegEx{Pattern: p.AddressQuery.Query, Options: p.AddressQuery.Options} } } // string if p.Location { switch p.LocationQuery.Operation { case "eq": q["address"] = p.LocationQuery.Query case "regex": q["address"] = bson.RegEx{Pattern: p.LocationQuery.Query, Options: p.LocationQuery.Options} } } // int64 if p.Age { switch p.AgeQuery.Operation { case "eq": q["age"] = p.AgeQuery.From case "gt-lt": q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lt": p.AgeQuery.To} case "gte-lte": q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lte": p.AgeQuery.To} case "gte-lt": q["age"] = bson.M{"$gte": p.AgeQuery.From, "$lt": p.AgeQuery.To} case "gt-lte": q["age"] = bson.M{"$gt": p.AgeQuery.From, "$lte": p.AgeQuery.To} } } // float64 if p.Price { switch p.PriceQuery.Operation { case "eq": q["age"] = p.PriceQuery.From case "gt-lt": q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lt": p.PriceQuery.To} case "gte-lte": q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lte": p.PriceQuery.To} case "gte-lt": q["age"] = bson.M{"$gte": p.PriceQuery.From, "$lt": p.PriceQuery.To} case "gt-lte": q["age"] = bson.M{"$gt": p.PriceQuery.From, "$lte": p.PriceQuery.To} } } // bool if p.Enabled { q["enabled"] = p.EnabledQuery.Query } m := new(model.Data) rq := c.Find(q) if e := rq.One(m); e != nil { return nil, e } return m, nil } func (r *DataRepository) Create(m *model.Data) error { ms := r.ms.Copy() defer ms.Close() c := ms.DB(r.database).C(r.collection) return c.Insert(m) } func (r *DataRepository) UpdateId(id string, m *model.Data) error { if !bson.IsObjectIdHex(id) { return errors.New(fmt.Sprintf("%s is not an ObjectId", id)) } ms := r.ms.Copy() defer ms.Close() c := ms.DB(r.database).C(r.collection) return c.UpdateId(bson.ObjectIdHex(id), m) } func (r *DataRepository) RemoveId(id string) error { if !bson.IsObjectIdHex(id) { return errors.New(fmt.Sprintf("%s is not an ObjectId", id)) } ms := r.ms.Copy() defer ms.Close() c := ms.DB(r.database).C(r.collection) return c.RemoveId(bson.ObjectIdHex(id)) }