// GetByIDs retrieves items by ID from Mongo. func GetByIDs(context interface{}, db *db.DB, ids []string) ([]Item, error) { log.Dev(context, "GetByIDs", "Started : IDs%v", ids) // Get the items from Mongo. var items []Item f := func(c *mgo.Collection) error { q := bson.M{"item_id": bson.M{"$in": ids}} log.Dev(context, "Find", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q)) return c.Find(q).All(&items) } if err := db.ExecuteMGO(context, Collection, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } log.Error(context, "GetByIDs", err, "Completed") return items, err } // If we got an unexpected number of items, throw an error. if len(ids) < len(items) { return nil, fmt.Errorf("Expected %d items, got %d: ", len(ids), len(items)) } log.Dev(context, "GetByIDs", "Completed") return items, nil }
// Create adds a new Submission based on a given Form into // the MongoDB database collection. func Create(context interface{}, db *db.DB, formID string, submission *Submission) error { log.Dev(context, "Create", "Started : Form[%s]", formID) if !bson.IsObjectIdHex(formID) { log.Error(context, "Create", ErrInvalidID, "Completed") return ErrInvalidID } if err := submission.Validate(); err != nil { return err } // FIXME: handle Number field maybe with https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/ to resolve race condition count, err := Count(context, db, formID) if err != nil { log.Error(context, "Create", err, "Completed") return err } submission.Number = count + 1 f := func(c *mgo.Collection) error { log.Dev(context, "Create", "MGO : db.%s.insert(%s)", c.Name, mongo.Query(submission)) return c.Insert(submission) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "Create", err, "Completed") return err } log.Dev(context, "Create", "Completed") return nil }
// GetByName retrieves the document for the specified Set. func GetByName(context interface{}, db *db.DB, name string) (*Set, error) { log.Dev(context, "GetByName", "Started : Name[%s]", name) key := "gbn" + name if v, found := cache.Get(key); found { set := v.(Set) log.Dev(context, "GetByName", "Completed : CACHE : Set[%+v]", &set) return &set, nil } var set Set f := func(c *mgo.Collection) error { q := bson.M{"name": name} log.Dev(context, "GetByName", "MGO : db.%s.findOne(%s)", c.Name, mongo.Query(q)) return c.Find(q).One(&set) } if err := db.ExecuteMGO(context, Collection, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } log.Error(context, "GetByName", err, "Completed") return nil, err } // Fix the set so it can be used for processing. set.PrepareForUse() cache.Set(key, set, gc.DefaultExpiration) log.Dev(context, "GetByName", "Completed : Set[%+v]", &set) return &set, nil }
// GetAll retrieves a list of regexs. func GetAll(context interface{}, db *db.DB, tags []string) ([]Regex, error) { log.Dev(context, "GetAll", "Started : Tags[%v]", tags) key := "grs" + strings.Join(tags, "-") if v, found := cache.Get(key); found { rgxs := v.([]Regex) log.Dev(context, "GetAll", "Completed : CACHE : Rgxs[%d]", len(rgxs)) return rgxs, nil } var rgxs []Regex f := func(c *mgo.Collection) error { log.Dev(context, "GetAll", "MGO : db.%s.find({}).sort([\"name\"])", c.Name) return c.Find(nil).All(&rgxs) } if err := db.ExecuteMGO(context, Collection, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } log.Error(context, "GetAll", err, "Completed") return nil, err } if rgxs == nil { log.Error(context, "GetAll", ErrNotFound, "Completed") return nil, ErrNotFound } cache.Set(key, rgxs, gc.DefaultExpiration) log.Dev(context, "GetAll", "Completed : Rgxs[%d]", len(rgxs)) return rgxs, nil }
// UpdateStatus updates a form submissions status inside the MongoDB database // collection. func UpdateStatus(context interface{}, db *db.DB, id, status string) (*Submission, error) { log.Dev(context, "UpdateStatus", "Started : Submission[%s]", id) if !bson.IsObjectIdHex(id) { log.Error(context, "UpdateStatus", ErrInvalidID, "Completed") return nil, ErrInvalidID } objectID := bson.ObjectIdHex(id) f := func(c *mgo.Collection) error { u := bson.M{ "$set": bson.M{ "status": status, "date_updated": time.Now(), }, } log.Dev(context, "UpdateStatus", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(objectID), mongo.Query(u)) return c.UpdateId(objectID, u) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "UpdateStatus", err, "Completed") return nil, err } submission, err := Retrieve(context, db, id) if err != nil { log.Error(context, "UpdateStatus", err, "Completed") return nil, err } log.Dev(context, "UpdateStatus", "Completed") return submission, nil }
// RetrieveMany retrieves a list of Submission's from the MongoDB database collection. func RetrieveMany(context interface{}, db *db.DB, ids []string) ([]Submission, error) { log.Dev(context, "RetrieveMany", "Started") var objectIDs = make([]bson.ObjectId, len(ids)) for i, id := range ids { if !bson.IsObjectIdHex(id) { log.Error(context, "RetrieveMany", ErrInvalidID, "Completed") return nil, ErrInvalidID } objectIDs[i] = bson.ObjectIdHex(id) } var submissions []Submission f := func(c *mgo.Collection) error { q := bson.M{ "_id": bson.M{ "$in": objectIDs, }, } log.Dev(context, "RetrieveMany", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q)) return c.Find(q).All(&submissions) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "RetrieveMany", err, "Completed") return nil, err } log.Dev(context, "RetrieveMany", "Started") return submissions, nil }
// Update updates the form gallery in the MongoDB database // collection. func Update(context interface{}, db *db.DB, id string, gallery *Gallery) error { log.Dev(context, "Update", "Started : Gallery[%s]", id) if !bson.IsObjectIdHex(id) { log.Error(context, "Update", ErrInvalidID, "Completed") return ErrInvalidID } if err := gallery.Validate(); err != nil { log.Error(context, "Update", err, "Completed") return err } objectID := bson.ObjectIdHex(id) gallery.DateUpdated = time.Now() f := func(c *mgo.Collection) error { log.Dev(context, "Update", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(objectID), mongo.Query(gallery)) return c.UpdateId(objectID, gallery) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "Update", err, "Completed") return err } log.Dev(context, "Update", "Completed") return nil }
// Retrieve retrieves a form gallery from the MongoDB database // collection as well as hydrating the form gallery with form submissions. func Retrieve(context interface{}, db *db.DB, id string) (*Gallery, error) { log.Dev(context, "Retrieve", "Started : Gallery[%s]", id) if !bson.IsObjectIdHex(id) { log.Error(context, "Retrieve", ErrInvalidID, "Completed") return nil, ErrInvalidID } objectID := bson.ObjectIdHex(id) var gallery Gallery f := func(c *mgo.Collection) error { log.Dev(context, "Retrieve", "MGO : db.%s.find(%s)", c.Name, mongo.Query(objectID)) return c.FindId(objectID).One(&gallery) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "Retrieve", err, "Completed") return nil, err } if err := hydrate(context, db, &gallery); err != nil { log.Error(context, "Retrieve", err, "Completed") return nil, err } log.Dev(context, "Retrieve", "Completed") return &gallery, nil }
// List retrives the form galleries for a given form from the MongoDB database // collection. func List(context interface{}, db *db.DB, formID string) ([]Gallery, error) { log.Dev(context, "List", "Started") if !bson.IsObjectIdHex(formID) { log.Error(context, "List", ErrInvalidID, "Completed") return nil, ErrInvalidID } formObjectID := bson.ObjectIdHex(formID) var galleries = make([]Gallery, 0) f := func(c *mgo.Collection) error { q := bson.M{ "form_id": formObjectID, } log.Dev(context, "List", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q)) return c.Find(q).All(&galleries) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "List", err, "Completed") return nil, err } if err := hydrateMany(context, db, galleries); err != nil { log.Error(context, "List", err, "Completed") return nil, err } log.Dev(context, "List", "Completed") return galleries, nil }
// Count returns the count of current submissions for a given // form id in the Form Submissions MongoDB database collection. func Count(context interface{}, db *db.DB, formID string) (int, error) { log.Dev(context, "Count", "Completed : Form[%s]", formID) if !bson.IsObjectIdHex(formID) { log.Error(context, "Count", ErrInvalidID, "Completed") return 0, ErrInvalidID } formObjectID := bson.ObjectIdHex(formID) var count int f := func(c *mgo.Collection) error { var err error q := bson.M{ "form_id": formObjectID, } log.Dev(context, "Count", "MGO : db.%s.find(%s).count()", c.Name, mongo.Query(q)) count, err = c.Find(q).Count() return err } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "Count", err, "Completed") return 0, err } log.Dev(context, "Count", "Completed") return count, nil }
// GetByName retrieves the document for the specified query mask. func GetByName(context interface{}, db *db.DB, collection string, field string) (Mask, error) { log.Dev(context, "GetByName", "Started : Collection[%s] Field[%s]", collection, field) key := "gbn" + collection + field if v, found := cache.Get(key); found { mask := v.(Mask) log.Dev(context, "GetByName", "Completed : CACHE : Mask[%+v]", mask) return mask, nil } var mask Mask f := func(c *mgo.Collection) error { q := bson.M{"collection": collection, "field": field} log.Dev(context, "GetByName", "MGO : db.%s.findOne(%s)", c.Name, mongo.Query(q)) return c.Find(q).One(&mask) } if err := db.ExecuteMGO(context, Collection, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } log.Error(context, "GetByName", err, "Completed") return Mask{}, err } cache.Set(key, mask, gc.DefaultExpiration) log.Dev(context, "GetByName", "Completed : Mask[%+v]", mask) return mask, nil }
// RemoveFlag removes a flag from a given Submission in // the MongoDB database collection. func RemoveFlag(context interface{}, db *db.DB, id, flag string) (*Submission, error) { log.Dev(context, "RemoveFlag", "Started : Submission[%s]", id) if !bson.IsObjectIdHex(id) { log.Error(context, "RemoveFlag", ErrInvalidID, "Completed") return nil, ErrInvalidID } objectID := bson.ObjectIdHex(id) f := func(c *mgo.Collection) error { u := bson.M{ "$pull": bson.M{ "flags": flag, }, } log.Dev(context, "RemoveFlag", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(objectID), mongo.Query(u)) return c.UpdateId(objectID, u) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "RemoveFlag", err, "Completed") return nil, err } submission, err := Retrieve(context, db, id) if err != nil { log.Error(context, "RemoveFlag", err, "Completed") return nil, err } log.Dev(context, "RemoveFlag", "Completed") return submission, nil }
// Remove removes forms in Mongo that match a given pattern. func Remove(context interface{}, db *db.DB, pattern string) error { f := func(c *mgo.Collection) error { q := bson.M{"header.title": bson.RegEx{Pattern: "^" + pattern}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, form.Collection, f); err != nil { return err } if err := db.ExecuteMGO(context, submission.Collection, f); err != nil { return err } return nil }
// Remove removes relationships, views, and patterns in Mongo that match a given pattern. func Remove(context interface{}, db *db.DB, prefix string) error { f := func(c *mgo.Collection) error { q := bson.M{"item_id": bson.RegEx{Pattern: prefix}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, item.Collection, f); err != nil { return err } f = func(c *mgo.Collection) error { q := bson.M{"predicate": bson.RegEx{Pattern: prefix}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, relationship.Collection, f); err != nil { return err } f = func(c *mgo.Collection) error { q := bson.M{"name": bson.RegEx{Pattern: prefix}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, view.Collection, f); err != nil { return err } f = func(c *mgo.Collection) error { q := bson.M{"type": bson.RegEx{Pattern: prefix}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, pattern.Collection, f); err != nil { return err } return nil }
// viewItems retrieves the items corresponding to the provided list of item IDs. func viewItems(context interface{}, db *db.DB, v *view.View, ids []string, embeds embeddedRels) ([]bson.M, error) { // Form the query. var results []item.Item f := func(c *mgo.Collection) error { return c.Find(bson.M{"item_id": bson.M{"$in": ids}}).All(&results) } // Execute the query. if err := db.ExecuteMGO(context, v.Collection, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } return nil, err } // Group the embedded relationships by item and predicate/tag. embedByItem, err := groupEmbeds(embeds) if err != nil { return nil, err } // Embed any related item IDs in the returned items. var output []bson.M if len(embedByItem) > 0 { for _, result := range results { // Get the respective IDs to embed. itemEmbeds, ok := embedByItem[result.ID] if ok { relMap := make(map[string]interface{}) for k, v := range itemEmbeds { relMap[k] = v } result.Related = relMap } // Convert to bson.M for output. itemBSON := bson.M{ "item_id": result.ID, "type": result.Type, "version": result.Version, "data": result.Data, "created_at": result.CreatedAt, "updated_at": result.UpdatedAt, "related": result.Related, } output = append(output, itemBSON) } } return output, nil }
// Remove removes patterns in Mongo that match a given prefix. func Remove(context interface{}, db *db.DB, prefix string) error { f := func(c *mgo.Collection) error { q := bson.M{"type": bson.RegEx{Pattern: prefix}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, pattern.Collection, f); err != nil { return err } return nil }
// Add inserts a regex for testing. func Add(db *db.DB, rgx regex.Regex) error { f := func(c *mgo.Collection) error { q := bson.M{"name": rgx.Name} _, err := c.Upsert(q, rgx) return err } if err := db.ExecuteMGO(tests.Context, regex.Collection, f); err != nil { return err } return nil }
// Add inserts a mask for testing. func Add(db *db.DB, msk mask.Mask) error { f := func(c *mgo.Collection) error { q := bson.M{"collection": msk.Collection, "field": msk.Field} _, err := c.Upsert(q, msk) return err } if err := db.ExecuteMGO(tests.Context, mask.Collection, f); err != nil { return err } return nil }
// Remove removes relationships in Mongo that match a given pattern. func Remove(context interface{}, db *db.DB, pattern string) error { f := func(c *mgo.Collection) error { q := bson.M{"predicate": bson.RegEx{Pattern: pattern}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, relationship.Collection, f); err != nil { return err } return nil }
// Remove removes gallerys in Mongo that match a given pattern. func Remove(context interface{}, db *db.DB, pattern string) error { f := func(c *mgo.Collection) error { q := bson.M{"description": bson.RegEx{Pattern: "^" + pattern}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(context, gallery.Collection, f); err != nil { return err } return nil }
// Remove is used to clear out all the test masks from the collection. func Remove(db *db.DB, collection string) error { f := func(c *mgo.Collection) error { q := bson.M{"$or": []bson.M{bson.M{"collection": collection}, bson.M{"collection": "*", "field": "test"}}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(tests.Context, mask.Collection, f); err != nil { return err } f = func(c *mgo.Collection) error { q := bson.M{"$or": []bson.M{bson.M{"collection": collection}, bson.M{"collection": "*", "field": "test"}}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(tests.Context, mask.CollectionHistory, f); err != nil { return err } return nil }
// Remove is used to clear out all the test sets from the collection. // All test documents must start with QSTEST in their name. func Remove(db *db.DB, pattern string) error { f := func(c *mgo.Collection) error { q := bson.M{"name": bson.RegEx{Pattern: pattern}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(tests.Context, query.Collection, f); err != nil { return err } f = func(c *mgo.Collection) error { q := bson.M{"name": bson.RegEx{Pattern: pattern}} _, err := c.RemoveAll(q) return err } if err := db.ExecuteMGO(tests.Context, query.CollectionHistory, f); err != nil { return err } return nil }
// RemoveAnswer adds an answer to a form gallery. Duplicated answers // are de-duplicated automatically and will not return an error. func RemoveAnswer(context interface{}, db *db.DB, id, submissionID, answerID string) (*Gallery, error) { log.Dev(context, "RemoveAnswer", "Started : Gallery[%s]", id) if !bson.IsObjectIdHex(id) { log.Error(context, "RemoveAnswer", ErrInvalidID, "Completed") return nil, ErrInvalidID } if !bson.IsObjectIdHex(submissionID) { log.Error(context, "RemoveAnswer", ErrInvalidID, "Completed") return nil, ErrInvalidID } objectID := bson.ObjectIdHex(id) answer := Answer{ SubmissionID: bson.ObjectIdHex(submissionID), AnswerID: answerID, } if err := answer.Validate(); err != nil { log.Error(context, "RemoveAnswer", err, "Completed") return nil, err } f := func(c *mgo.Collection) error { u := bson.M{ "$pull": bson.M{ "answers": answer, }, } log.Dev(context, "RemoveAnswer", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(objectID), mongo.Query(u)) return c.UpdateId(objectID, u) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "RemoveAnswer", err, "Completed") return nil, err } gallery, err := Retrieve(context, db, id) if err != nil { log.Error(context, "RemoveAnswer", err, "Completed") return nil, err } log.Dev(context, "RemoveAnswer", "Completed") return gallery, nil }
// GetLastHistoryByName gets the last written Set within the history. func GetLastHistoryByName(context interface{}, db *db.DB, name string) (*Set, error) { log.Dev(context, "GetLastHistoryByName", "Started : Name[%s]", name) type rslt struct { Name string `bson:"name"` Sets []Set `bson:"sets"` } key := "glhbn" + name if v, found := cache.Get(key); found { result := v.(rslt) log.Dev(context, "GetLastHistoryByName", "Completed : CACHE : Set[%+v]", &result.Sets[0]) return &result.Sets[0], nil } var result rslt f := func(c *mgo.Collection) error { q := bson.M{"name": name} proj := bson.M{"sets": bson.M{"$slice": 1}} log.Dev(context, "GetLastHistoryByName", "MGO : db.%s.find(%s,%s)", c.Name, mongo.Query(q), mongo.Query(proj)) return c.Find(q).Select(proj).One(&result) } if err := db.ExecuteMGO(context, CollectionHistory, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } log.Error(context, "GetLastHistoryByName", err, "Complete") return nil, err } if result.Sets == nil { err := errors.New("History not found") log.Error(context, "GetLastHistoryByName", err, "Complete") return nil, err } // Fix the set so it can be used for processing. result.Sets[0].PrepareForUse() cache.Set(key, result, gc.DefaultExpiration) log.Dev(context, "GetLastHistoryByName", "Completed : Set[%+v]", &result.Sets[0]) return &result.Sets[0], nil }
// UpdateAnswer updates the edited answer if it could find it // inside the MongoDB database collection atomically. func UpdateAnswer(context interface{}, db *db.DB, id string, answer AnswerInput) (*Submission, error) { log.Dev(context, "UpdateAnswer", "Started : Submission[%s]", id) if !bson.IsObjectIdHex(id) { log.Error(context, "UpdateAnswer", ErrInvalidID, "Completed") return nil, ErrInvalidID } if err := answer.Validate(); err != nil { log.Error(context, "UpdateAnswer", ErrInvalidID, "Completed") return nil, ErrInvalidID } objectID := bson.ObjectIdHex(id) f := func(c *mgo.Collection) error { q := bson.M{ "_id": objectID, "replies.widget_id": answer.WidgetID, } // Update the nested subdocument using the $ projection operator: // https://docs.mongodb.com/manual/reference/operator/update/positional/ u := bson.M{ "$set": bson.M{ "replies.$.edited": answer.Answer, }, } log.Dev(context, "UpdateAnswer", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(q), mongo.Query(u)) return c.Update(q, u) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "UpdateAnswer", err, "Completed") return nil, err } submission, err := Retrieve(context, db, id) if err != nil { log.Error(context, "UpdateAnswer", err, "Completed") return nil, err } log.Dev(context, "UpdateAnswer", "Completed") return submission, nil }
// Delete removes a relationship from from Mongo. func Delete(context interface{}, db *db.DB, predicate string) error { log.Dev(context, "Delete", "Started : Predicate[%s]", predicate) // Remove the relationship. f := func(c *mgo.Collection) error { q := bson.M{"predicate": predicate} log.Dev(context, "Remove", "MGO : db.%s.remove(%s)", c.Name, mongo.Query(q)) return c.Remove(q) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "Delete", err, "Completed") return err } log.Dev(context, "Delete", "Completed") return nil }
// List retrieves a list of forms from the MongodB database collection. func List(context interface{}, db *db.DB, limit, skip int) ([]Form, error) { log.Dev(context, "List", "Started") var forms = make([]Form, 0) f := func(c *mgo.Collection) error { log.Dev(context, "List", "MGO : db.%s.find().limit(%d).skip(%d)", c.Name, limit, skip) return c.Find(nil).Limit(limit).Skip(skip).All(&forms) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "List", err, "Completed") return nil, err } log.Dev(context, "List", "Completed") return forms, nil }
// Delete removes an item from from Mongo. func Delete(context interface{}, db *db.DB, id string) error { log.Dev(context, "Delete", "Started : ID[%s]", id) // Remove the item. f := func(c *mgo.Collection) error { q := bson.M{"item_id": id} log.Dev(context, "Remove", "MGO : db.%s.remove(%s)", c.Name, mongo.Query(q)) return c.Remove(q) } if err := db.ExecuteMGO(context, Collection, f); err != nil { log.Error(context, "Delete", err, "Completed") return err } log.Dev(context, "Delete", "Completed") return nil }
// GetLastHistoryByName gets the last written query mask within the history. func GetLastHistoryByName(context interface{}, db *db.DB, collection string, field string) (Mask, error) { log.Dev(context, "GetLastHistoryByName", "Started : Collection[%s] Field[%s]", collection, field) type rslt struct { Name string `bson:"name"` Masks []Mask `bson:"masks"` } key := "glhbn" + collection + field if v, found := cache.Get(key); found { result := v.(rslt) log.Dev(context, "GetLastHistoryByName", "Completed : CACHE : Set[%+v]", result.Masks[0]) return result.Masks[0], nil } var result rslt f := func(c *mgo.Collection) error { q := bson.M{"collection": collection, "field": field} proj := bson.M{"masks": bson.M{"$slice": 1}} log.Dev(context, "GetLastHistoryByName", "MGO : db.%s.find(%s,%s)", c.Name, mongo.Query(q), mongo.Query(proj)) return c.Find(q).Select(proj).One(&result) } if err := db.ExecuteMGO(context, CollectionHistory, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } log.Error(context, "GetLastHistoryByName", err, "Complete") return Mask{}, err } if result.Masks == nil { err := errors.New("History not found") log.Error(context, "GetLastHistoryByName", err, "Complete") return Mask{}, err } cache.Set(key, result, gc.DefaultExpiration) log.Dev(context, "GetLastHistoryByName", "Completed : Set[%+v]", result.Masks[0]) return result.Masks[0], nil }
// GetLastHistoryByName gets the last written Regex within the history. func GetLastHistoryByName(context interface{}, db *db.DB, name string) (Regex, error) { log.Dev(context, "GetLastHistoryByName", "Started : Name[%s]", name) type rslt struct { Name string `bson:"name"` Regexs []Regex `bson:"regexs"` } key := "glhbn" + name if v, found := cache.Get(key); found { result := v.(rslt) log.Dev(context, "GetLastHistoryByName", "Completed : CACHE : Regex[%+v]", &result.Regexs[0]) return result.Regexs[0], nil } var result rslt f := func(c *mgo.Collection) error { q := bson.M{"name": name} proj := bson.M{"regexs": bson.M{"$slice": 1}} log.Dev(context, "GetLastHistoryByName", "MGO : db.%s.find(%s,%s)", c.Name, mongo.Query(q), mongo.Query(proj)) return c.Find(q).Select(proj).One(&result) } if err := db.ExecuteMGO(context, CollectionHistory, f); err != nil { if err == mgo.ErrNotFound { err = ErrNotFound } log.Error(context, "GetLastHistoryByName", err, "Complete") return Regex{}, err } if result.Regexs == nil { err := errors.New("History not found") log.Error(context, "GetLastHistoryByName", err, "Complete") return Regex{}, err } cache.Set(key, result, gc.DefaultExpiration) log.Dev(context, "GetLastHistoryByName", "Completed : Regex[%+v]", &result.Regexs[0]) return result.Regexs[0], nil }