func (u *User) AddRole(roleName string, contextValue string) error { _, err := permission.FindRole(roleName) if err != nil { return err } conn, err := db.Conn() if err != nil { return err } defer conn.Close() err = conn.Users().Update(bson.M{"email": u.Email}, bson.M{ "$addToSet": bson.M{ // Order matters in $addToSet, that's why bson.D is used instead // of bson.M. "roles": bson.D([]bson.DocElem{ {Name: "name", Value: roleName}, {Name: "contextvalue", Value: contextValue}, }), }, }) if err != nil { return err } return u.Reload() }
func (h *NodeHealer) UpdateNodeData(nodeData provision.NodeStatusData) error { node, err := h.findNodeForNodeData(nodeData) if err != nil { return fmt.Errorf("[node healer update] %s", err) } isSuccess := true for _, c := range nodeData.Checks { isSuccess = c.Successful if isSuccess == false { break } } now := time.Now().UTC() toInsert := nodeStatusData{ LastUpdate: now, } if isSuccess { toInsert.LastSuccess = now } coll, err := nodeDataCollection() if err != nil { return err } defer coll.Close() _, err = coll.UpsertId(node.Address, bson.M{ "$set": toInsert, "$push": bson.M{ "checks": bson.D([]bson.DocElem{ {Name: "$each", Value: []nodeChecks{{Time: now, Checks: nodeData.Checks}}}, {Name: "$slice", Value: -10}, }), }, }) return err }
func (h *NodeHealer) UpdateNodeData(node provision.Node, checks []provision.NodeCheckResult) error { isSuccess := true for _, c := range checks { isSuccess = c.Successful if !isSuccess { break } } now := time.Now().UTC() toInsert := NodeStatusData{ LastUpdate: now, } if isSuccess { toInsert.LastSuccess = now } coll, err := nodeDataCollection() if err != nil { return err } defer coll.Close() _, err = coll.UpsertId(node.Address(), bson.M{ "$set": toInsert, "$push": bson.M{ "checks": bson.D([]bson.DocElem{ {Name: "$each", Value: []NodeChecks{{Time: now, Checks: checks}}}, {Name: "$slice", Value: -10}, }), }, }) return err }
func (m *Config) setSelectServers(s *mgo.Session) { if len(m.Tags) == 0 { return } s.SelectServers(bson.D(m.Tags)) s.Refresh() }
func (s *mongodbStorage) StoreImage(repo, id, host string) error { coll := s.getColl("images_history") defer coll.Database.Session.Close() _, err := coll.UpsertId(repo, bson.M{ "$addToSet": bson.M{"history": bson.D([]bson.DocElem{ // Order is important for $addToSet! bson.DocElem{Name: "node", Value: host}, bson.DocElem{Name: "imageid", Value: id}, })}, "$set": bson.M{"lastnode": host, "lastid": id}, }) return err }
// extractFieldByName takes a field name and document, and returns a value representing // the value of that field in the document in a format that can be printed as a string. // It will also handle dot-delimited field names for nested arrays or documents. func extractFieldByName(fieldName string, document interface{}) interface{} { dotParts := strings.Split(fieldName, ".") var subdoc interface{} = document for _, path := range dotParts { docValue := reflect.ValueOf(subdoc) if !docValue.IsValid() { return "" } docType := docValue.Type() docKind := docType.Kind() if docKind == reflect.Map { subdocVal := docValue.MapIndex(reflect.ValueOf(path)) if subdocVal.Kind() == reflect.Invalid { return "" } subdoc = subdocVal.Interface() } else if docKind == reflect.Slice { if docType == marshalDType { // dive into a D as a document asD := bson.D(subdoc.(bsonutil.MarshalD)) var err error subdoc, err = bsonutil.FindValueByKey(path, &asD) if err != nil { return "" } } else { // check that the path can be converted to int arrayIndex, err := strconv.Atoi(path) if err != nil { return "" } // bounds check for slice if arrayIndex < 0 || arrayIndex >= docValue.Len() { return "" } subdocVal := docValue.Index(arrayIndex) if subdocVal.Kind() == reflect.Invalid { return "" } subdoc = subdocVal.Interface() } } else { // trying to index into a non-compound type - just return blank. return "" } } return subdoc }
func (u *User) RemoveRole(roleName string, contextValue string) error { conn, err := db.Conn() if err != nil { return err } defer conn.Close() err = conn.Users().Update(bson.M{"email": u.Email}, bson.M{ "$pull": bson.M{ "roles": bson.D([]bson.DocElem{ {Name: "name", Value: roleName}, {Name: "contextvalue", Value: contextValue}, }), }, }) if err != nil { return err } return u.Reload() }
func (s getterSetterD) GetBSON() (interface{}, error) { if len(s) == 0 { return bson.D{}, nil } return bson.D(s[:len(s)-1]), nil }
// GetBSONValueAsJSON is equivalent to ConvertBSONValueToJSON, but does not mutate its argument. func GetBSONValueAsJSON(x interface{}) (interface{}, error) { switch v := x.(type) { case nil: return nil, nil case bool: return v, nil case *bson.M: // document doc, err := getConvertedKeys(*v) if err != nil { return nil, err } return doc, err case bson.M: // document return getConvertedKeys(v) case map[string]interface{}: return getConvertedKeys(v) case bson.D: out := bson.D{} for _, value := range v { jsonValue, err := GetBSONValueAsJSON(value.Value) if err != nil { return nil, err } out = append(out, bson.DocElem{ Name: value.Name, Value: jsonValue, }) } return MarshalD(out), nil case MarshalD: out, err := GetBSONValueAsJSON(bson.D(v)) if err != nil { return nil, err } return MarshalD(out.(bson.D)), nil case []interface{}: // array out := []interface{}{} for _, value := range v { jsonValue, err := GetBSONValueAsJSON(value) if err != nil { return nil, err } out = append(out, jsonValue) } return out, nil case string: return v, nil // require no conversion case int: return json.NumberInt(v), nil case bson.ObjectId: // ObjectId return json.ObjectId(v.Hex()), nil case bson.Decimal128: return json.Decimal128{v}, nil case time.Time: // Date return json.Date(v.Unix()*1000 + int64(v.Nanosecond()/1e6)), nil case int64: // NumberLong return json.NumberLong(v), nil case int32: // NumberInt return json.NumberInt(v), nil case float64: return json.NumberFloat(v), nil case float32: return json.NumberFloat(float64(v)), nil case []byte: // BinData (with generic type) data := base64.StdEncoding.EncodeToString(v) return json.BinData{0x00, data}, nil case bson.Binary: // BinData data := base64.StdEncoding.EncodeToString(v.Data) return json.BinData{v.Kind, data}, nil case mgo.DBRef: // DBRef return json.DBRef{v.Collection, v.Id, v.Database}, nil case bson.DBPointer: // DBPointer return json.DBPointer{v.Namespace, v.Id}, nil case bson.RegEx: // RegExp return json.RegExp{v.Pattern, v.Options}, nil case bson.MongoTimestamp: // Timestamp timestamp := int64(v) return json.Timestamp{ Seconds: uint32(timestamp >> 32), Increment: uint32(timestamp), }, nil case bson.JavaScript: // JavaScript var scope interface{} var err error if v.Scope != nil { scope, err = GetBSONValueAsJSON(v.Scope) if err != nil { return nil, err } } return json.JavaScript{v.Code, scope}, nil default: switch x { case bson.MinKey: // MinKey return json.MinKey{}, nil case bson.MaxKey: // MaxKey return json.MaxKey{}, nil case bson.Undefined: // undefined return json.Undefined{}, nil } } return nil, fmt.Errorf("conversion of BSON value '%v' of type '%T' not supported", x, x) }
// txnOpInsert returns a single transaction operation that will update // the already stored document. func (b *storageDBWrapper) txnOpUpdate(id string, updates ...bson.DocElem) txn.Op { op := b.txnOpBase(id) op.Assert = txn.DocExists op.Update = bson.D{{"$set", bson.D(updates)}} return op }