Пример #1
0
// 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
}
Пример #2
0
func matchAnswers(t *testing.T, ga gallery.Answer, sub submission.Submission, sa submission.Answer) {
	if ga.SubmissionID.Hex() != sub.ID.Hex() {
		t.Fatalf("\t%s\tShould match the submission ID : Expected %s, got %s", tests.Failed, sub.ID.Hex(), ga.SubmissionID.Hex())
	}
	t.Logf("\t%s\tShould match the submission ID", tests.Success)

	if ga.AnswerID != sa.WidgetID {
		t.Fatalf("\t%s\tShould match the widget ID : Expected %s, got %s", tests.Failed, sa.WidgetID, ga.AnswerID)
	}
	t.Logf("\t%s\tShould match the widget ID", tests.Success)

	if mongo.Query(ga.Answer.Answer) != mongo.Query(sa.Answer) {
		t.Fatalf("\t%s\tShould match the answer : Expected %s, got %s", tests.Failed, mongo.Query(sa.Answer), mongo.Query(ga.Answer.Answer))
	}
	t.Logf("\t%s\tShould match the answer.", tests.Success)
}
Пример #3
0
// 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
}
Пример #4
0
// 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
}
Пример #5
0
// 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
}
Пример #6
0
// 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
}
Пример #7
0
// 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
}
Пример #8
0
// 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
}
Пример #9
0
// 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
}
Пример #10
0
// 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
}
Пример #11
0
// 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
}
Пример #12
0
// 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
}
Пример #13
0
// Upsert upserts an item to the items collections.
func Upsert(context interface{}, db *db.DB, item *Item) error {
	log.Dev(context, "Upsert", "Started : ID[%s]", item.ID)

	// If there is no ID, create one.
	if item.ID == "" {
		item.ID = uuid.New()
	}

	// If CreatedAt is not set, set it. Usually, CreatedAt is joined with the setting of the ID.
	// In our case, custom ids may be created outside this package for new items. For these
	// cases we check that a CreatedAt is not yet set.
	if item.CreatedAt.IsZero() {
		item.CreatedAt = time.Now()
	}

	// Always update UpdatedAt.
	item.UpdatedAt = time.Now()

	// Validate the item.
	if err := item.Validate(); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	// Upsert the item.
	f := func(c *mgo.Collection) error {
		q := bson.M{"item_id": item.ID}
		log.Dev(context, "Upsert", "MGO : db.%s.upsert(%s, %s)", c.Name, mongo.Query(q), mongo.Query(item))
		_, err := c.Upsert(q, item)
		return err
	}
	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	log.Dev(context, "Upsert", "Completed")
	return nil
}
Пример #14
0
// 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
}
Пример #15
0
// Upsert upserts a pattern to the collection of currently utilized patterns.
func Upsert(context interface{}, db *db.DB, pattern *Pattern) error {
	log.Dev(context, "Upsert", "Started : Type[%s]", pattern.Type)

	// Validate the pattern.
	if err := pattern.Validate(); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	// Upsert the pattern.
	f := func(c *mgo.Collection) error {
		q := bson.M{"type": pattern.Type}
		log.Dev(context, "Upsert", "MGO : db.%s.upsert(%s, %s)", c.Name, mongo.Query(q), mongo.Query(pattern))
		_, err := c.Upsert(q, pattern)
		return err
	}
	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	log.Dev(context, "Upsert", "Completed")
	return nil
}
Пример #16
0
// Upsert upserts a relationship to the collection of currently utilized relationships.
func Upsert(context interface{}, db *db.DB, rel *Relationship) error {
	log.Dev(context, "Upsert", "Started : Predicate[%s]", rel.Predicate)

	// Validate the relationship.
	if err := rel.Validate(); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	// Upsert the relationship.
	f := func(c *mgo.Collection) error {
		q := bson.M{"predicate": rel.Predicate}
		log.Dev(context, "Upsert", "MGO : db.%s.upsert(%s, %s)", c.Name, mongo.Query(q), mongo.Query(rel))
		_, err := c.Upsert(q, rel)
		return err
	}
	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	log.Dev(context, "Upsert", "Completed")
	return nil
}
Пример #17
0
// Upsert upserts a view to the collection of currently utilized views.
func Upsert(context interface{}, db *db.DB, view *View) error {
	log.Dev(context, "Upsert", "Started : Name[%s]", view.Name)

	// Validate the view.
	if err := view.Validate(); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	// Upsert the view.
	f := func(c *mgo.Collection) error {
		q := bson.M{"name": view.Name}
		log.Dev(context, "Upsert", "MGO : db.%s.upsert(%s, %s)", c.Name, mongo.Query(q), mongo.Query(view))
		_, err := c.Upsert(q, view)
		return err
	}
	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	log.Dev(context, "Upsert", "Completed")
	return nil
}
Пример #18
0
// 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
}
Пример #19
0
// 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
}
Пример #20
0
// 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
}
Пример #21
0
// 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
}
Пример #22
0
// 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
}
Пример #23
0
// 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
}
Пример #24
0
// GetNames retrieves a list of query names.
func GetNames(context interface{}, db *db.DB) ([]string, error) {
	log.Dev(context, "GetNames", "Started")

	var rawNames []struct {
		Name string
	}

	key := "gns"
	if v, found := cache.Get(key); found {
		names := v.([]string)
		log.Dev(context, "GetNames", "Completed : CACHE : Sets[%d]", len(names))
		return names, nil
	}

	f := func(c *mgo.Collection) error {
		s := bson.M{"name": 1}
		log.Dev(context, "GetNames", "MGO : db.%s.find({}, %s).sort([\"name\"])", c.Name, mongo.Query(s))
		return c.Find(nil).Select(s).Sort("name").All(&rawNames)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		if err == mgo.ErrNotFound {
			err = ErrNotFound
		}

		log.Error(context, "GetNames", err, "Completed")
		return nil, err
	}

	if rawNames == nil {
		log.Error(context, "GetNames", ErrNotFound, "Completed")
		return nil, ErrNotFound
	}

	names := make([]string, len(rawNames))
	for i := range rawNames {
		names[i] = rawNames[i].Name
	}

	cache.Set(key, names, gc.DefaultExpiration)

	log.Dev(context, "GetNames", "Completed : Sets[%d]", len(names))
	return names, nil
}
Пример #25
0
// Upsert upserts the provided form into the MongoDB database collection.
func Upsert(context interface{}, db *db.DB, form *Form) error {
	log.Dev(context, "Upsert", "Started")

	var isNewForm bool

	// If there is no ID probided, we should set one as this is an Upsert
	// operation. It is also important to remember if this was a new form or not
	// because we need to update the stats if this wasn't a new form.
	if form.ID.Hex() == "" {
		form.ID = bson.NewObjectId()
		isNewForm = true
		form.DateCreated = time.Now()
	}

	form.DateUpdated = time.Now()

	if err := form.Validate(); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	f := func(c *mgo.Collection) error {
		log.Dev(context, "Upsert", "MGO : db.%s.upsert(%s, %s)", c.Name, mongo.Query(form.ID.Hex()), mongo.Query(form))
		_, err := c.UpsertId(form.ID, form)
		return err
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Upsert", err, "Completed")
		return err
	}

	// New forms don't have any stats so don't bother updating it.
	if !isNewForm {
		if _, err := UpdateStats(context, db, form.ID.Hex()); err != nil {
			log.Error(context, "Upsert", err, "Completed")
			return err
		}
	}

	log.Dev(context, "Upsert", "Completed")
	return nil
}
Пример #26
0
// EnsureIndexes perform index create commands against Mongo for the indexes
// specied in each query for the set. It will attempt to ensure all indexes
// regardless if one fails. Then reports all failures.
func EnsureIndexes(context interface{}, db *db.DB, set *Set) error {
	log.Dev(context, "EnsureIndexes", "Started : Name[%s]", set.Name)

	var errStr string

	for _, q := range set.Queries {
		if len(q.Indexes) == 0 {
			continue
		}

		f := func(c *mgo.Collection) error {
			for _, idx := range q.Indexes {
				mgoIdx := mgo.Index{
					Key:        idx.Key,
					Unique:     idx.Unique,
					DropDups:   idx.DropDups,
					Background: idx.Background,
					Sparse:     idx.Sparse,
				}

				log.Dev(context, "EnsureIndexes", "MGO : db.%s.ensureindex(%s)", c.Name, mongo.Query(mgoIdx))
				if err := c.EnsureIndex(mgoIdx); err != nil {
					log.Error(context, "EnsureIndexes", err, "Ensuring Index")
					errStr += fmt.Sprintf("[%s:%s] ", strings.Join(idx.Key, ","), err.Error())
				}
			}

			return nil
		}

		if err := db.ExecuteMGO(context, q.Collection, f); err != nil {
			log.Error(context, "EnsureIndexes", err, "Completed")
			return err
		}
	}

	if errStr != "" {
		return errors.New(errStr)
	}

	log.Dev(context, "EnsureIndexes", "Completed")
	return nil
}
Пример #27
0
// GetByCollection retrieves the masks for the specified collection.
func GetByCollection(context interface{}, db *db.DB, collection string) (map[string]Mask, error) {
	log.Dev(context, "GetByCollection", "Started : Collection[%s]", collection)

	key := "gbc" + collection
	if v, found := cache.Get(key); found {
		mskMap := v.(map[string]Mask)
		log.Dev(context, "GetByCollection", "Completed : CACHE : Masks[%d]", len(mskMap))
		return mskMap, nil
	}

	var masks []Mask
	f := func(c *mgo.Collection) error {
		q := bson.M{"$or": []bson.M{bson.M{"collection": collection}, bson.M{"collection": "*"}}}
		log.Dev(context, "GetByCollection", "MGO : db.%s.findOne(%s)", c.Name, mongo.Query(q))
		return c.Find(q).All(&masks)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		if err == mgo.ErrNotFound {
			err = ErrNotFound
		}

		log.Error(context, "GetByCollection", err, "Completed")
		return nil, err
	}

	if masks == nil {
		log.Error(context, "GetByCollection", ErrNotFound, "Completed")
		return nil, ErrNotFound
	}

	mskMap := make(map[string]Mask, len(masks))
	for _, msk := range masks {
		mskMap[msk.Field] = msk
	}

	cache.Set(key, mskMap, gc.DefaultExpiration)

	log.Dev(context, "GetByCollection", "Completed : Masks[%d]", len(mskMap))
	return mskMap, nil
}
Пример #28
0
// GetByPredicate retrieves a relationship by predicate from Mongo.
func GetByPredicate(context interface{}, db *db.DB, predicate string) (*Relationship, error) {
	log.Dev(context, "GetByPredicate", "Started : Predicate[%s]", predicate)

	// Get the relationship from Mongo.
	var rel Relationship
	f := func(c *mgo.Collection) error {
		q := bson.M{"predicate": predicate}
		log.Dev(context, "Find", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q))
		return c.Find(q).One(&rel)
	}
	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		if err == mgo.ErrNotFound {
			err = ErrNotFound
		}
		log.Error(context, "GetByPredicate", err, "Completed")
		return &rel, err
	}

	log.Dev(context, "GetByPredicate", "Completed")
	return &rel, nil
}
Пример #29
0
// GetByType retrieves a pattern by type from Mongo.
func GetByType(context interface{}, db *db.DB, itemType string) (*Pattern, error) {
	log.Dev(context, "GetByType", "Started : Type[%s]", itemType)

	// Get the pattern from Mongo.
	var pattern Pattern
	f := func(c *mgo.Collection) error {
		q := bson.M{"type": itemType}
		log.Dev(context, "Find", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q))
		return c.Find(q).One(&pattern)
	}
	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		if err == mgo.ErrNotFound {
			err = ErrNotFound
		}
		log.Error(context, "GetByType", err, "Completed")
		return &pattern, err
	}

	log.Dev(context, "GetByType", "Completed")
	return &pattern, nil
}
Пример #30
0
// GetByID retrieves a single item by ID from Mongo.
func GetByID(context interface{}, db *db.DB, id string) (Item, error) {
	log.Dev(context, "GetByID", "Started : ID[%s]", id)

	// Get the items from Mongo.
	var itm Item
	f := func(c *mgo.Collection) error {
		q := bson.M{"item_id": id}
		log.Dev(context, "GetByID", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q))
		return c.Find(q).One(&itm)
	}
	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		if err == mgo.ErrNotFound {
			err = ErrNotFound
		}
		log.Error(context, "GetByID", err, "Completed")
		return itm, err
	}

	log.Dev(context, "GetByID", "Completed")
	return itm, nil
}