github.com/holochain/holochain-proto@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/action_getlinks.go (about) 1 package holochain 2 3 import ( 4 "encoding/json" 5 "fmt" 6 . "github.com/holochain/holochain-proto/hash" 7 peer "github.com/libp2p/go-libp2p-peer" 8 "reflect" 9 ) 10 11 //------------------------------------------------------------ 12 // GetLinks 13 14 type APIFnGetLinks struct { 15 action ActionGetLinks 16 } 17 18 func (fn *APIFnGetLinks) Name() string { 19 return fn.action.Name() 20 } 21 22 func (fn *APIFnGetLinks) Args() []Arg { 23 return []Arg{{Name: "base", Type: HashArg}, {Name: "tag", Type: StringArg}, {Name: "options", Type: MapArg, MapType: reflect.TypeOf(GetLinksOptions{}), Optional: true}} 24 } 25 26 func (fn *APIFnGetLinks) Call(h *Holochain) (response interface{}, err error) { 27 var r interface{} 28 a := &fn.action 29 r, err = h.dht.Query(a.linkQuery.Base, GETLINK_REQUEST, *a.linkQuery) 30 31 if err == nil { 32 switch t := r.(type) { 33 case *LinkQueryResp: 34 response = t 35 if a.options.Load { 36 for i := range t.Links { 37 var hash Hash 38 hash, err = NewHash(t.Links[i].H) 39 if err != nil { 40 return 41 } 42 opts := GetOptions{GetMask: GetMaskEntryType + GetMaskEntry, StatusMask: StatusDefault} 43 req := GetReq{H: hash, StatusMask: StatusDefault, GetMask: opts.GetMask} 44 var rsp interface{} 45 rsp, err = callGet(h, req, &opts) 46 if err == nil { 47 // TODO: bleah, really this should be another of those 48 // case statements that choses the encoding baste on 49 // entry type, time for a refactor! 50 entry := rsp.(GetResp).Entry 51 switch content := entry.Content().(type) { 52 case string: 53 t.Links[i].E = content 54 case []byte: 55 var j []byte 56 j, err = json.Marshal(content) 57 if err != nil { 58 return 59 } 60 t.Links[i].E = string(j) 61 default: 62 err = fmt.Errorf("bad type in entry content: %T:%v", content, content) 63 } 64 t.Links[i].EntryType = rsp.(GetResp).EntryType 65 } 66 //TODO better error handling here, i.e break out of the loop and return if error? 67 } 68 } 69 default: 70 err = fmt.Errorf("unexpected response type from SendGetLinks: %T", t) 71 } 72 } 73 return 74 } 75 76 type ActionGetLinks struct { 77 linkQuery *LinkQuery 78 options *GetLinksOptions 79 } 80 81 func NewGetLinksAction(linkQuery *LinkQuery, options *GetLinksOptions) *ActionGetLinks { 82 a := ActionGetLinks{linkQuery: linkQuery, options: options} 83 return &a 84 } 85 86 func (a *ActionGetLinks) Name() string { 87 return "getLinks" 88 } 89 90 func (a *ActionGetLinks) SysValidation(h *Holochain, d *EntryDef, pkg *Package, sources []peer.ID) (err error) { 91 //@TODO what sys level getlinks validation? That they are all valid hash format for the DNA? 92 return 93 } 94 95 func (a *ActionGetLinks) Receive(dht *DHT, msg *Message) (response interface{}, err error) { 96 lq := msg.Body.(LinkQuery) 97 var r LinkQueryResp 98 r.Links, err = dht.GetLinks(lq.Base, lq.T, lq.StatusMask) 99 response = &r 100 101 return 102 }