client: Support json selectors in retrieval
This commit is contained in:
parent
81a2f2f06d
commit
08e297a217
@ -8,6 +8,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/ipld/go-car"
|
"github.com/ipld/go-car"
|
||||||
carv2 "github.com/ipld/go-car/v2"
|
carv2 "github.com/ipld/go-car/v2"
|
||||||
carv2bs "github.com/ipld/go-car/v2/blockstore"
|
carv2bs "github.com/ipld/go-car/v2/blockstore"
|
||||||
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-padreader"
|
"github.com/filecoin-project/go-padreader"
|
||||||
@ -845,6 +847,14 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref
|
|||||||
sel := selectorparse.CommonSelector_ExploreAllRecursively
|
sel := selectorparse.CommonSelector_ExploreAllRecursively
|
||||||
if order.DatamodelPathSelector != nil {
|
if order.DatamodelPathSelector != nil {
|
||||||
|
|
||||||
|
if strings.HasPrefix(string(*order.DatamodelPathSelector), "{") {
|
||||||
|
var err error
|
||||||
|
sel, err = selectorparse.ParseJSONSelector(string(*order.DatamodelPathSelector))
|
||||||
|
if err != nil {
|
||||||
|
finish(xerrors.Errorf("failed to parse json-selector '%s': %w", *order.DatamodelPathSelector, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any)
|
ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any)
|
||||||
|
|
||||||
selspec, err := textselector.SelectorSpecFromPath(
|
selspec, err := textselector.SelectorSpecFromPath(
|
||||||
@ -866,6 +876,7 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref
|
|||||||
sel = selspec.Node()
|
sel = selspec.Node()
|
||||||
log.Infof("partial retrieval of datamodel-path-selector %s/*", *order.DatamodelPathSelector)
|
log.Infof("partial retrieval of datamodel-path-selector %s/*", *order.DatamodelPathSelector)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// summary:
|
// summary:
|
||||||
// 1. if we're retrieving from an import, FromLocalCAR will be set.
|
// 1. if we're retrieving from an import, FromLocalCAR will be set.
|
||||||
@ -1032,13 +1043,21 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref
|
|||||||
|
|
||||||
var subRootFound bool
|
var subRootFound bool
|
||||||
|
|
||||||
|
var sel datamodel.Node
|
||||||
|
|
||||||
// no err check - we just compiled this before starting, but now we do not wrap a `*`
|
// no err check - we just compiled this before starting, but now we do not wrap a `*`
|
||||||
|
if strings.HasPrefix(string(*order.DatamodelPathSelector), "{") {
|
||||||
|
sel, _ = selectorparse.ParseJSONSelector(string(*order.DatamodelPathSelector))
|
||||||
|
} else {
|
||||||
selspec, _ := textselector.SelectorSpecFromPath(*order.DatamodelPathSelector, nil) //nolint:errcheck
|
selspec, _ := textselector.SelectorSpecFromPath(*order.DatamodelPathSelector, nil) //nolint:errcheck
|
||||||
|
sel = selspec.Node()
|
||||||
|
}
|
||||||
|
|
||||||
if err := utils.TraverseDag(
|
if err := utils.TraverseDag(
|
||||||
ctx,
|
ctx,
|
||||||
ds,
|
ds,
|
||||||
root,
|
root,
|
||||||
selspec.Node(),
|
sel,
|
||||||
func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error {
|
func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error {
|
||||||
if r == traversal.VisitReason_SelectionMatch {
|
if r == traversal.VisitReason_SelectionMatch {
|
||||||
|
|
||||||
@ -1046,9 +1065,13 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref
|
|||||||
return xerrors.Errorf("unsupported selection path '%s' does not correspond to a block boundary (a.k.a. CID link)", p.Path.String())
|
return xerrors.Errorf("unsupported selection path '%s' does not correspond to a block boundary (a.k.a. CID link)", p.Path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.LastBlock.Link == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
cidLnk, castOK := p.LastBlock.Link.(cidlink.Link)
|
cidLnk, castOK := p.LastBlock.Link.(cidlink.Link)
|
||||||
if !castOK {
|
if !castOK {
|
||||||
return xerrors.Errorf("cidlink cast unexpectedly failed on '%s'", p.LastBlock.Link.String())
|
return xerrors.Errorf("cidlink cast unexpectedly failed on '%s'", p.LastBlock.Link)
|
||||||
}
|
}
|
||||||
|
|
||||||
root = cidLnk.Cid
|
root = cidLnk.Cid
|
||||||
|
Loading…
Reference in New Issue
Block a user