retrieval: Drop the RootSelector hack

This commit is contained in:
Łukasz Magiera 2021-11-23 17:42:43 +01:00
parent bdac11ade7
commit 407c2ed114
3 changed files with 25 additions and 32 deletions

View File

@ -210,14 +210,9 @@ type RestrievalRes struct {
type Selector string type Selector string
type DagSpec struct { type DagSpec struct {
// RootSelector specifies root node
// - when using textselector, the path specifies the root node
// - if nil then RootSelector is inferred from DataSelector
// - must match a single node
RootSelector *Selector
// DataSelector matches data to be retrieved // DataSelector matches data to be retrieved
// - when using textselector, the path specifies subtree // - when using textselector, the path specifies subtree
// - the matched graph must have a single root
DataSelector *Selector DataSelector *Selector
} }
@ -226,9 +221,8 @@ type ExportRef struct {
// DAGs array specifies a list of DAGs to export // DAGs array specifies a list of DAGs to export
// - If exporting into a car file, defines car roots // - If exporting into a car file, defines car roots
// - If exporting into unixfs files, only one DAG is supported, DataSelector is ignored // - If exporting into unixfs files, only one DAG is supported, DataSelector is only used to find the root node
// - When not specified defaults to a single DAG: // - When not specified defaults to a single DAG:
// - Root - the root node: `{".": {}}`
// - Data - the entire DAG: `{"R":{"l":{"none":{}},":>":{"a":{">":{"@":{}}}}}}` // - Data - the entire DAG: `{"R":{"l":{"none":{}},":>":{"a":{">":{"@":{}}}}}}`
DAGs []DagSpec DAGs []DagSpec

View File

@ -451,39 +451,35 @@ var clientRetrieveLsCmd = &cli.Command{
ctx := ReqContext(cctx) ctx := ReqContext(cctx)
afmt := NewAppFmt(cctx.App) afmt := NewAppFmt(cctx.App)
rootSelector := lapi.Selector(`{".": {}}`) dataSelector := lapi.Selector(fmt.Sprintf(`{"R":{"l":{"depth":%d},":>":{"a":{">":{"|":[{"@":{}},{".":{}}]}}}}}`, cctx.Int("depth")))
dataSelector := lapi.Selector(fmt.Sprintf(`{"a":{">":{"R":{"l":{"depth":%d},":>":{"a":{">":{"|":[{"@":{}},{".":{}}]}}}}}}}`, cctx.Int("depth")))
if cctx.IsSet("datamodel-path") { if cctx.IsSet("datamodel-path") {
rootSelector, err = pathToSel(cctx.String("datamodel-path"), nil)
if err != nil {
return err
}
ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any) ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any)
dataSelector, err = pathToSel(cctx.String("datamodel-path"), ssb.ExploreAll( dataSelector, err = pathToSel(cctx.String("datamodel-path"),
ssb.ExploreRecursive(selector.RecursionLimitDepth(int64(cctx.Int("depth"))), ssb.ExploreAll(ssb.ExploreUnion(ssb.Matcher(), ssb.ExploreRecursiveEdge()))), ssb.ExploreUnion(
)) ssb.Matcher(),
ssb.ExploreAll(
ssb.ExploreRecursive(selector.RecursionLimitDepth(int64(cctx.Int("depth"))), ssb.ExploreAll(ssb.ExploreUnion(ssb.Matcher(), ssb.ExploreRecursiveEdge()))),
)))
if err != nil { if err != nil {
return err return xerrors.Errorf("parsing datamodel path: %w", err)
} }
} }
eref, err := retrieve(ctx, cctx, fapi, &dataSelector, afmt.Printf) eref, err := retrieve(ctx, cctx, fapi, &dataSelector, afmt.Printf)
if err != nil { if err != nil {
return err return xerrors.Errorf("retrieve: %w", err)
} }
fmt.Println() // separate retrieval events from results fmt.Println() // separate retrieval events from results
eref.DAGs = append(eref.DAGs, lapi.DagSpec{ eref.DAGs = append(eref.DAGs, lapi.DagSpec{
RootSelector: &rootSelector,
DataSelector: &dataSelector, DataSelector: &dataSelector,
}) })
rc, err := ClientExportStream(ainfo.Addr, ainfo.AuthHeader(), *eref, true) rc, err := ClientExportStream(ainfo.Addr, ainfo.AuthHeader(), *eref, true)
if err != nil { if err != nil {
return err return xerrors.Errorf("export: %w", err)
} }
defer rc.Close() // nolint defer rc.Close() // nolint

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -1024,26 +1025,26 @@ func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds forma
out := make([]dagSpec, len(dsp)) out := make([]dagSpec, len(dsp))
for i, spec := range dsp { for i, spec := range dsp {
if spec.RootSelector == nil {
spec.RootSelector = spec.DataSelector
}
if spec.RootSelector != nil { // if a selector is specified, find it's root node
if spec.DataSelector != nil {
var rsn ipld.Node var rsn ipld.Node
if strings.HasPrefix(string(*spec.RootSelector), "{") { if strings.HasPrefix(string(*spec.DataSelector), "{") {
var err error var err error
rsn, err = selectorparse.ParseJSONSelector(string(*spec.RootSelector)) rsn, err = selectorparse.ParseJSONSelector(string(*spec.DataSelector))
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to parse json-selector '%s': %w", *spec.RootSelector, err) return nil, xerrors.Errorf("failed to parse json-selector '%s': %w", *spec.DataSelector, err)
} }
} else { } else {
selspec, _ := textselector.SelectorSpecFromPath(textselector.Expression(*spec.RootSelector), nil) //nolint:errcheck selspec, _ := textselector.SelectorSpecFromPath(textselector.Expression(*spec.DataSelector), nil) //nolint:errcheck
rsn = selspec.Node() rsn = selspec.Node()
} }
var newRoot cid.Cid var newRoot cid.Cid
var errHalt = errors.New("halt walk")
if err := utils.TraverseDag( if err := utils.TraverseDag(
ctx, ctx,
ds, ds,
@ -1061,7 +1062,7 @@ func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds forma
// todo: is the n ipld.Node above the node we want as the (sub)root? // todo: is the n ipld.Node above the node we want as the (sub)root?
// todo: how to go from ipld.Node to a cid? // todo: how to go from ipld.Node to a cid?
newRoot = root newRoot = root
return nil return errHalt
} }
cidLnk, castOK := p.LastBlock.Link.(cidlink.Link) cidLnk, castOK := p.LastBlock.Link.(cidlink.Link)
@ -1070,10 +1071,12 @@ func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds forma
} }
newRoot = cidLnk.Cid newRoot = cidLnk.Cid
return errHalt
} }
return nil return nil
}, },
); err != nil { ); err != nil && err != errHalt {
return nil, xerrors.Errorf("error while locating partial retrieval sub-root: %w", err) return nil, xerrors.Errorf("error while locating partial retrieval sub-root: %w", err)
} }