super-graph/core/remote.go
2020-04-10 02:27:43 -04:00

254 lines
5.1 KiB
Go

package core
// import (
// "bytes"
// "errors"
// "fmt"
// "net/http"
// "sync"
// "github.com/cespare/xxhash/v2"
// "github.com/dosco/super-graph/jsn"
// "github.com/dosco/super-graph/core/internal/qcode"
// )
// func execRemoteJoin(st *stmt, data []byte, hdr http.Header) ([]byte, error) {
// var err error
// if len(data) == 0 || st.skipped == 0 {
// return data, nil
// }
// sel := st.qc.Selects
// h := xxhash.New()
// // fetch the field name used within the db response json
// // that are used to mark insertion points and the mapping between
// // those field names and their select objects
// fids, sfmap := parentFieldIds(h, sel, st.skipped)
// // fetch the field values of the marked insertion points
// // these values contain the id to be used with fetching remote data
// from := jsn.Get(data, fids)
// var to []jsn.Field
// switch {
// case len(from) == 1:
// to, err = resolveRemote(hdr, h, from[0], sel, sfmap)
// case len(from) > 1:
// to, err = resolveRemotes(hdr, h, from, sel, sfmap)
// default:
// return nil, errors.New("something wrong no remote ids found in db response")
// }
// if err != nil {
// return nil, err
// }
// var ob bytes.Buffer
// err = jsn.Replace(&ob, data, from, to)
// if err != nil {
// return nil, err
// }
// return ob.Bytes(), nil
// }
// func resolveRemote(
// hdr http.Header,
// h *xxhash.Digest,
// field jsn.Field,
// sel []qcode.Select,
// sfmap map[uint64]*qcode.Select) ([]jsn.Field, error) {
// // replacement data for the marked insertion points
// // key and value will be replaced by whats below
// toA := [1]jsn.Field{}
// to := toA[:1]
// // use the json key to find the related Select object
// k1 := xxhash.Sum64(field.Key)
// s, ok := sfmap[k1]
// if !ok {
// return nil, nil
// }
// p := sel[s.ParentID]
// // then use the Table nme in the Select and it's parent
// // to find the resolver to use for this relationship
// k2 := mkkey(h, s.Name, p.Name)
// r, ok := rmap[k2]
// if !ok {
// return nil, nil
// }
// id := jsn.Value(field.Value)
// if len(id) == 0 {
// return nil, nil
// }
// //st := time.Now()
// b, err := r.Fn(hdr, id)
// if err != nil {
// return nil, err
// }
// if len(r.Path) != 0 {
// b = jsn.Strip(b, r.Path)
// }
// var ob bytes.Buffer
// if len(s.Cols) != 0 {
// err = jsn.Filter(&ob, b, colsToList(s.Cols))
// if err != nil {
// return nil, err
// }
// } else {
// ob.WriteString("null")
// }
// to[0] = jsn.Field{Key: []byte(s.FieldName), Value: ob.Bytes()}
// return to, nil
// }
// func resolveRemotes(
// hdr http.Header,
// h *xxhash.Digest,
// from []jsn.Field,
// sel []qcode.Select,
// sfmap map[uint64]*qcode.Select) ([]jsn.Field, error) {
// // replacement data for the marked insertion points
// // key and value will be replaced by whats below
// to := make([]jsn.Field, len(from))
// var wg sync.WaitGroup
// wg.Add(len(from))
// var cerr error
// for i, id := range from {
// // use the json key to find the related Select object
// k1 := xxhash.Sum64(id.Key)
// s, ok := sfmap[k1]
// if !ok {
// return nil, nil
// }
// p := sel[s.ParentID]
// // then use the Table nme in the Select and it's parent
// // to find the resolver to use for this relationship
// k2 := mkkey(h, s.Name, p.Name)
// r, ok := rmap[k2]
// if !ok {
// return nil, nil
// }
// id := jsn.Value(id.Value)
// if len(id) == 0 {
// return nil, nil
// }
// go func(n int, id []byte, s *qcode.Select) {
// defer wg.Done()
// //st := time.Now()
// b, err := r.Fn(hdr, id)
// if err != nil {
// cerr = fmt.Errorf("%s: %s", s.Name, err)
// return
// }
// if len(r.Path) != 0 {
// b = jsn.Strip(b, r.Path)
// }
// var ob bytes.Buffer
// if len(s.Cols) != 0 {
// err = jsn.Filter(&ob, b, colsToList(s.Cols))
// if err != nil {
// cerr = fmt.Errorf("%s: %s", s.Name, err)
// return
// }
// } else {
// ob.WriteString("null")
// }
// to[n] = jsn.Field{Key: []byte(s.FieldName), Value: ob.Bytes()}
// }(i, id, s)
// }
// wg.Wait()
// return to, cerr
// }
// func parentFieldIds(h *xxhash.Digest, sel []qcode.Select, skipped uint32) (
// [][]byte,
// map[uint64]*qcode.Select) {
// c := 0
// for i := range sel {
// s := &sel[i]
// if isSkipped(skipped, uint32(s.ID)) {
// c++
// }
// }
// // list of keys (and it's related value) to extract from
// // the db json response
// fm := make([][]byte, c)
// // mapping between the above extracted key and a Select
// // object
// sm := make(map[uint64]*qcode.Select, c)
// n := 0
// for i := range sel {
// s := &sel[i]
// if !isSkipped(skipped, uint32(s.ID)) {
// continue
// }
// p := sel[s.ParentID]
// k := mkkey(h, s.Name, p.Name)
// if r, ok := rmap[k]; ok {
// fm[n] = r.IDField
// n++
// k := xxhash.Sum64(r.IDField)
// sm[k] = s
// }
// }
// return fm, sm
// }
// func isSkipped(n uint32, pos uint32) bool {
// return ((n & (1 << pos)) != 0)
// }
// func colsToList(cols []qcode.Column) []string {
// var f []string
// for i := range cols {
// f = append(f, cols[i].Name)
// }
// return f
// }