record.go (108 lines of code) (raw):

package sfdc import ( "encoding/json" "errors" ) const ( // RecordAttributes is the attribute map from the record JSON RecordAttributes = "attributes" recordAttrType = "type" recordAttrURL = "url" ) // Record is a representation of a Salesforce // record. type Record struct { sobject string url string fields map[string]interface{} lookUps map[string]*Record } // RecordFromJSONMap creates a recrod from a JSON map. func RecordFromJSONMap(jsonMap map[string]interface{}) (*Record, error) { if jsonMap == nil { return nil, errors.New("record: map can not be nil") } r := &Record{} r.fromJSONMap(jsonMap) return r, nil } // UnmarshalJSON provides a custom unmarshaling of a // JSON byte array. func (r *Record) UnmarshalJSON(data []byte) error { if r == nil { return errors.New("record: can't unmarshal to a nil struct") } if data == nil { return errors.New("record: can't unmarshal to a nil byte array") } var jsonMap map[string]interface{} err := json.Unmarshal(data, &jsonMap) if err != nil { return err } r.fromJSONMap(jsonMap) return nil } func (r *Record) fromJSONMap(jsonMap map[string]interface{}) { r.fields = make(map[string]interface{}) r.lookUps = make(map[string]*Record) for k, v := range jsonMap { if k == RecordAttributes { if attr, ok := v.(map[string]interface{}); ok { if obj, ok := attr[recordAttrType]; ok { if sobj, ok := obj.(string); ok { r.sobject = sobj } } if obj, ok := attr[recordAttrURL]; ok { if url, ok := obj.(string); ok { r.url = url } } } } else { if v != nil { if obj, is := v.(map[string]interface{}); is == false { r.fields[k] = v } else { if r.isLookUp(obj) { if rec, err := RecordFromJSONMap(obj); err == nil { r.lookUps[k] = rec } } } } } } } func (r *Record) isLookUp(jsonMap map[string]interface{}) bool { _, has := jsonMap[RecordAttributes] return has } // LookUps returns all of the record's look ups func (r *Record) LookUps() []*Record { records := make([]*Record, len(r.lookUps)) var idx int for _, r := range r.lookUps { records[idx] = r idx++ } return records } // LookUp returns the look up record func (r *Record) LookUp(lookUp string) (*Record, bool) { if len(r.lookUps) == 0 { return nil, false } rec, has := r.lookUps[lookUp] return rec, has } // SObject returns attribute's Salesforce object name. func (r *Record) SObject() string { return r.sobject } // URL returns the record attribute's URL. func (r *Record) URL() string { return r.url } // FieldValue returns the field's value. If there is no field // for the field name, then false will be returned. func (r *Record) FieldValue(field string) (interface{}, bool) { value, has := r.fields[field] return value, has } // Fields returns the map of field name to value relationships. func (r *Record) Fields() map[string]interface{} { fields := make(map[string]interface{}) for k, v := range r.fields { fields[k] = v } return fields }