Documentation ¶
Overview ¶
Package textselector provides basic utilities for creation of IPLD selector objects from a flat textual representation. For further info see https://github.com/ipld/specs/blob/master/selectors/selectors.md
Example (SelectorFromPath) ¶
package main import ( "bytes" "context" "fmt" "io" "log" "github.com/ipfs/go-cid" mipld "github.com/ipfs/go-ipld-format" mdag "github.com/ipfs/go-merkledag" mdagtest "github.com/ipfs/go-merkledag/test" // .../Raw must be imported to init() Raw-codec support // Dag-PB is additionally configured runtime dagpb "github.com/ipld/go-codec-dagpb" _ "github.com/ipld/go-ipld-prime/codec/raw" "github.com/ipld/go-ipld-prime" cidlink "github.com/ipld/go-ipld-prime/linking/cid" basicnode "github.com/ipld/go-ipld-prime/node/basic" "github.com/ipld/go-ipld-prime/traversal" "github.com/ipld/go-ipld-prime/traversal/selector" textselector "github.com/ipld/go-ipld-selector-text-lite" ) func main() { // // we put together a fixture datastore, and also return its root ds, rootCid := fixtureDagService() // // Selector spec from a path, hopefully within that rootCid // The 001 is deliberate: making sure index navigation still works selectorSpec, err := textselector.SelectorSpecFromPath("Links/1/Hash/Links/001/Hash", false, nil) if err != nil { log.Fatal(err) } // // this is how we R/O interact with the fixture DS linkSystem := cidlink.DefaultLinkSystem() linkSystem.StorageReadOpener = func(lctx ipld.LinkContext, lnk ipld.Link) (io.Reader, error) { if cl, isCid := lnk.(cidlink.Link); !isCid { return nil, fmt.Errorf("unexpected link type %#v", lnk) } else { node, err := ds.Get(lctx.Ctx, cl.Cid) if err != nil { return nil, err } return bytes.NewBuffer(node.RawData()), nil } } // // this is what allows us to understand dagpb nodePrototypeChooser := dagpb.AddSupportToChooser( func(ipld.Link, ipld.LinkContext) (ipld.NodePrototype, error) { return basicnode.Prototype.Any, nil }, ) // // compile our selector from spec parsedSelector, err := selector.ParseSelector(selectorSpec.Node()) if err != nil { log.Fatal(err) } // // Not sure why this indirection exists TBH... // Also trapping it in a struct ( twice ) is ugh ctx := context.TODO() linkContext := ipld.LinkContext{Ctx: ctx} // // this is how we pull the root node out of the DS startNodePrototype, err := nodePrototypeChooser(cidlink.Link{Cid: rootCid}, linkContext) if err != nil { log.Fatal(err) } startNode, err := linkSystem.Load( linkContext, cidlink.Link{Cid: rootCid}, startNodePrototype, ) if err != nil { log.Fatal(err) } // // this is executing the selector over the entire DS err = traversal.Progress{ Cfg: &traversal.Config{ Ctx: ctx, LinkSystem: linkSystem, LinkTargetNodePrototypeChooser: nodePrototypeChooser, }, }.WalkAdv( startNode, parsedSelector, func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error { if r == traversal.VisitReason_SelectionMatch { content, _ := n.AsBytes() fmt.Printf("%s\n", content) } return nil }, ) if err != nil { log.Fatal(err) } } func fixtureDagService() (mipld.DAGService, cid.Cid) { ds := mdagtest.Mock() correct := mdag.NewRawNode([]byte("WantedNode")) incorrect := mdag.NewRawNode([]byte("UnwantedNode")) bothIncorrect := &mdag.ProtoNode{} bothIncorrect.AddNodeLink("a", incorrect) bothIncorrect.AddNodeLink("b", incorrect) bIsCorrect := &mdag.ProtoNode{} bIsCorrect.AddNodeLink("b", correct) bIsCorrect.AddNodeLink("a", incorrect) root := &mdag.ProtoNode{} root.AddNodeLink("", bothIncorrect) root.AddNodeLink("", bIsCorrect) ds.AddMany(context.Background(), []mipld.Node{ correct, incorrect, bothIncorrect, bIsCorrect, root, }) return ds, root.Cid() }
Output: WantedNode
Index ¶
Examples ¶
Constants ¶
View Source
const PathValidCharset = `[- _0-9a-zA-Z\/\.]`
PathValidCharset is the regular expression fully matching a valid textselector
Variables ¶
This section is empty.
Functions ¶
func SelectorSpecFromPath ¶
func SelectorSpecFromPath(path Expression, matchPath bool, optionalSubselectorAtTarget builder.SelectorSpec) (builder.SelectorSpec, error)
SelectorSpecFromPath transforms a textual path specification in the form x/y/10/z into a go-ipld-prime selector-spec object. This is a short-term stop-gap on the road to a more versatile text-based selector description mechanism. Therefore the accepted syntax is relatively inflexible, and restricted to the members of PathValidCharset. The parsing rules are:
- The character `/` is a path segment separator
- An empty segment ( `...//...` ) and the unix-like `.` and `..` are illegal
- Any other valid segment is treated as a key within a map, or (if applicable) as an index within an array
Types ¶
Click to show internal directories.
Click to hide internal directories.