// RunQuery will execute your query in keys only and store to dst results while returning
// a cursor for the next page. The length of dst will also override the limit for your returned query.
// If dst is nil, provide your own length by setting it in query like q.Limit(10)
RunQuery will execute your query in keys only and store to dst results while returning
a cursor for the next page. The length of dst will also override the limit for your returned query.
If dst is nil, provide your own length by setting it in query like q.Limit(10)
// RunQuery will execute your query in keys only and store to dst results while returning // a cursor for the next page . The length of dst will also override the limit for your returned query . // If dst is nil provide your own length by setting it in query like q . Limit ( 10 )
func (c *Client) RunQuery(ctx context.Context, q *datastore.Query, dst interface{}, cursor string) ([]*datastore.Key, string, error) {
	var keys []*datastore.Key
	var val reflect.Value
	q = q.KeysOnly()
	var limit int
	if dst != nil {
		val = reflect.ValueOf(dst)
		if val.Kind() != reflect.Slice {
			return keys, "", fmt.Errorf("dscache.Client.RunQuery: dst must be a slice of pointers")
		}
		limit = val.Len()
		q = q.Limit(limit)
	}
	if cursor != "" {
		c, err := datastore.DecodeCursor(cursor)
		if err != nil {
			return keys, "", fmt.Errorf("dscache.Client.RunQuery: invalid cursor %v", err)
		}
		q = q.Start(c)
	}
	t := c.DSClient.Run(ctx, q)
	for {
		if key, err := t.Next(nil); err == iterator.Done {
			break
		} else if err != nil {
			return keys, "", fmt.Errorf("dscache.Client.RunQuery: iterator error %v", err)
		} else {
			keys = append(keys, key)
		}
	}
	crsr, err := t.Cursor()
	if err != nil {
		return keys, "", fmt.Errorf("dscache.Client.RunQuery: cursor error %v", err)
	}
	kLen := len(keys)
	if kLen > 0 && kLen <= limit {
		cursor = crsr.String()
	} else {
		cursor = ""
	}
	if kLen > 0 && dst != nil {
		var ns reflect.Value
		if kLen < limit {
			ns = reflect.MakeSlice(val.Type(), kLen, kLen)
			dst = ns.Interface()
			cursor = ""
		}
		if err := c.GetMulti(ctx, keys, dst); err != nil {
			return keys, cursor, fmt.Errorf("dscache.Client.RunQuery: failed to populate dst %v", err)
		}
		if ns.Kind() == reflect.Slice {
			for idx := range keys {
				val.Index(idx).Set(ns.Index(idx))
			}
		}
	}
	return keys, cursor, nil
}
func ( c * Client ) RunQuery ( ctx context . Context , q * datastore . Query , dst interface { } , cursor string ) ( [ ] * datastore . Key , string , error ) { var keys [ ] * datastore . Key var val reflect . Value q = q . KeysOnly ( ) var limit int if dst != nil { val = reflect . ValueOf ( dst ) if val . Kind ( ) != reflect . Slice { return keys , " " , fmt . Errorf ( " " ) } limit = val . Len ( ) q = q . Limit ( limit ) } if cursor != " " { c , err := datastore . DecodeCursor ( cursor ) if err != nil { return keys , " " , fmt . Errorf ( " " , err ) } q = q . Start ( c ) } t := c . DSClient . Run ( ctx , q ) for { if key , err := t . Next ( nil ) ; err == iterator . Done { break } else if err != nil { return keys , " " , fmt . Errorf ( " " , err ) } else { keys = append ( keys , key ) } } crsr , err := t . Cursor ( ) if err != nil { return keys , " " , fmt . Errorf ( " " , err ) } kLen := len ( keys ) if kLen > 0 && kLen <= limit { cursor = crsr . String ( ) } else { cursor = " " } if kLen > 0 && dst != nil { var ns reflect . Value if kLen < limit { ns = reflect . MakeSlice ( val . Type ( ) , kLen , kLen ) dst = ns . Interface ( ) cursor = " " } if err := c . GetMulti ( ctx , keys , dst ) ; err != nil { return keys , cursor , fmt . Errorf ( " " , err ) } if ns . Kind ( ) == reflect . Slice { for idx := range keys { val . Index ( idx ) . Set ( ns . Index ( idx ) ) } } } return keys , cursor , nil }
RunQuery will execute your query in keys only and store to dst results while returning
a cursor for the next page.
RunQuery will execute your query in keys only and store to dst results while returning a cursor for the next page .
// create right size slice and let's just fill dst later