func ModifyChannels(db *mgo.Database) (err error) {
	Topics := db.C(topicsCollection)
	notNull := bson.M{"$ne": ""}
	query := bson.M{
		"user": notNull,
		"org":  notNull,
	}
	var topics []Topic

	// Modify user setting

	err = Topics.Find(query).All(&topics)
	handle_errors(err)

	for _, topic := range topics {
		channels := make([]models.Channel, 0)

		for _, name := range topic.Channels {
			channel := new(models.Channel)
			channel.Name = name
			channel.Enabled = true
			channels = append(channels, *channel)
		}

		Topics.Update(bson.M{"_id": topic.Id}, bson.M{
			"$set": bson.M{
				"channels": channels,
			},
		})
	}

	// fmt.Println("Updated", change.Updated, "documents in `", topicsCollection, "` collection")

	// Modify org setting

	query["user"] = ""
	change, err := Topics.UpdateAll(
		query,
		bson.M{
			"$set": map[string][]models.Channel{
				"channels": make([]models.Channel, 0),
			},
		},
	)
	handle_errors(err)
	fmt.Println("Updated", change.Updated, "documents in `", topicsCollection, "` collection")

	return
}
예제 #2
0
파일: dbapi.go 프로젝트: josjevv/khabar
// InsertOrUpdateTopic adds a topic in `topics` collection if it doesn't exist
// Or it update the topic if it exists
//
// This is not a very effecient way of doing it but we are doing it at the cost
// of the data structure we want.
//
// One of the limitations is that mongo is not yet capable of upserting to array
// of documents. For this to happen in a simple way the data structure has to
// change from channels: []Channel to channels: map[string]interface
func InsertOrUpdateTopic(org, ident, channelName, attr string, val bool, user string) error {

	var channels []db.Channel
	var channel db.Channel
	var doc utils.M
	var spec utils.M

	found := new(db.Topic)
	query := utils.M{
		"org":   org,
		"user":  user, // empty for org
		"ident": ident,
	}

	// See if this setting already exists
	err := db.Conn.GetOne(
		db.TopicCollection,
		query,
		found,
	)

	// Fetch the global setting
	// Because if the above setting already doesn't exist, then set the other
	// attr to what is set in global

	global := new(db.Topic)
	q := utils.M{"org": "", "user": "", "ident": ident}
	e := db.Conn.GetOne(db.TopicCollection, q, &global)

	if e == nil {
		for _, ch := range global.Channels {
			if ch.Name == channelName {
				if attr == "Default" {
					channel.Locked = ch.Locked
				} else if attr == "Locked" {
					channel.Default = ch.Default
				}
			} else if err != nil {
				channels = append(channels, ch)
			}
		}
	}

	channel.Name = channelName

	if attr == "Default" {
		channel.Default = val
	} else if attr == "Locked" {
		channel.Locked = val
	} else {
		channel.Enabled = val
	}

	channels = append(channels, channel)

	// If it doesn't exist, insert and return

	if err != nil {
		topic := new(db.Topic)
		topic.PrepareSave()
		topic.Ident = ident
		topic.Organization = org
		topic.User = user
		topic.Channels = channels
		Insert(topic)
		return nil
	}

	// If it does exist, find the document in the array and modify it
	// Do one of the two depending on whether its present or not
	// Step 1. if its not present, add to channels array
	// Step 2. if its present, set the value

	query["channels.name"] = channelName
	err = db.Conn.GetOne(
		db.TopicCollection,
		query,
		found,
	)

	// Step 1. Add to set and return

	if err != nil {
		doc = utils.M{
			"$addToSet": utils.M{
				"channels": channel,
			},
		}
		delete(query, "channels.name")
		return updateTopics(query, doc)
	}

	// Step 2. Else set the value

	if attr == "Default" {
		spec = utils.M{
			"channels.$.default": val,
		}
	} else if attr == "Locked" {
		spec = utils.M{
			"channels.$.locked": val,
		}
	} else if attr == "Enabled" {
		spec = utils.M{
			"channels.$.enabled": val,
		}
	}

	doc = utils.M{
		"$set": spec,
	}

	return updateTopics(query, doc)
}