diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 0a58defd936..e144865dc80 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -4,10 +4,11 @@ import ( "fmt" "io" "math" + "strings" "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coredag" - "github.com/ipfs/go-ipfs/pin" path "gx/ipfs/QmNYPETsdAu2uQ1k9q9S1jYEGURaLHV6cbYRSVFVRftpF8/go-path" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" @@ -65,7 +66,7 @@ into an object of the specified format. cmdkit.StringOption("hash", "Hash function to use").WithDefault(""), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - nd, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -87,12 +88,11 @@ into an object of the specified format. } } - cids := cid.NewSet() - b := ipld.NewBatch(req.Context, nd.DAG) - + var adder ipld.NodeAdder = api.Dag() if dopin { - defer nd.Blockstore.PinLock().Unlock() + adder = api.Dag().Pinning() } + b := ipld.NewBatch(req.Context, adder) it := req.Files.Entries() for it.Next() { @@ -116,7 +116,6 @@ into an object of the specified format. } cid := nds[0].Cid() - cids.Add(cid) if err := res.Emit(&OutputObject{Cid: cid}); err != nil { return err } @@ -129,17 +128,6 @@ into an object of the specified format. return err } - if dopin { - cids.ForEach(func(c cid.Cid) error { - nd.Pinning.PinWithMode(c, pin.Recursive) - return nil - }) - - err := nd.Pinning.Flush() - if err != nil { - return err - } - } return nil }, Type: OutputObject{}, @@ -167,27 +155,29 @@ format. cmdkit.StringArg("ref", true, false, "The object to get").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - nd, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } - p, err := path.ParsePath(req.Arguments[0]) + p, err := iface.ParsePath(req.Arguments[0]) if err != nil { return err } - lastCid, rem, err := nd.Resolver.ResolveToLastNode(req.Context, p) + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } - obj, err := nd.DAG.Get(req.Context, lastCid) + + obj, err := api.Dag().Get(req.Context, rp.Cid()) if err != nil { return err } var out interface{} = obj - if len(rem) > 0 { + if len(rp.Remainder()) > 0 { + rem := strings.Split(rp.Remainder(), "/") final, _, err := obj.Resolve(rem) if err != nil { return err @@ -210,24 +200,24 @@ var DagResolveCmd = &cmds.Command{ cmdkit.StringArg("ref", true, false, "The path to resolve").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - nd, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } - p, err := path.ParsePath(req.Arguments[0]) + p, err := iface.ParsePath(req.Arguments[0]) if err != nil { return err } - lastCid, rem, err := nd.Resolver.ResolveToLastNode(req.Context, p) + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } return cmds.EmitOnce(res, &ResolveOutput{ - Cid: lastCid, - RemPath: path.Join(rem), + Cid: rp.Cid(), + RemPath: rp.Remainder(), }) }, Encoders: cmds.EncoderMap{ diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index ee1d7089480..e91f4c88159 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -18,12 +18,13 @@ import ( "errors" "fmt" "github.com/ipfs/go-ipfs/core" - coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - "github.com/ipfs/go-ipfs/core/coreapi/interface/options" "github.com/ipfs/go-ipfs/namesys" "github.com/ipfs/go-ipfs/pin" "github.com/ipfs/go-ipfs/repo" + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" pstore "gx/ipfs/QmPiemjiKBC9VA7vZF82m4x1oygtg2c2YVqag8PX7dN1BD/go-libp2p-peerstore" @@ -96,8 +97,11 @@ func (api *CoreAPI) Block() coreiface.BlockAPI { } // Dag returns the DagAPI interface implementation backed by the go-ipfs node -func (api *CoreAPI) Dag() ipld.DAGService { - return api.dag +func (api *CoreAPI) Dag() coreiface.APIDagService { + return &dagAPI{ + api.dag, + api, + } } // Name returns the NameAPI interface implementation backed by the go-ipfs node diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go new file mode 100644 index 00000000000..272f809d33d --- /dev/null +++ b/core/coreapi/dag.go @@ -0,0 +1,53 @@ +package coreapi + +import ( + "context" + + "github.com/ipfs/go-ipfs/pin" + + cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" +) + +type dagAPI struct { + ipld.DAGService + + core *CoreAPI +} + +type pinningAdder CoreAPI + +func (adder *pinningAdder) Add(ctx context.Context, nd ipld.Node) error { + defer adder.blockstore.PinLock().Unlock() + + if err := adder.dag.Add(ctx, nd); err != nil { + return err + } + + adder.pinning.PinWithMode(nd.Cid(), pin.Recursive) + + return adder.pinning.Flush() +} + +func (adder *pinningAdder) AddMany(ctx context.Context, nds []ipld.Node) error { + defer adder.blockstore.PinLock().Unlock() + + if err := adder.dag.AddMany(ctx, nds); err != nil { + return err + } + + cids := cid.NewSet() + + for _, nd := range nds { + c := nd.Cid() + if cids.Visit(c) { + adder.pinning.PinWithMode(c, pin.Recursive) + } + } + + return adder.pinning.Flush() +} + +func (api *dagAPI) Pinning() ipld.NodeAdder { + return (*pinningAdder)(api.core) +} diff --git a/core/coreapi/interface/coreapi.go b/core/coreapi/interface/coreapi.go index 9d2100fcc50..16b28182e6f 100644 --- a/core/coreapi/interface/coreapi.go +++ b/core/coreapi/interface/coreapi.go @@ -19,7 +19,7 @@ type CoreAPI interface { Block() BlockAPI // Dag returns an implementation of Dag API - Dag() ipld.DAGService + Dag() APIDagService // Name returns an implementation of Name API Name() NameAPI diff --git a/core/coreapi/interface/dag.go b/core/coreapi/interface/dag.go new file mode 100644 index 00000000000..455d0045035 --- /dev/null +++ b/core/coreapi/interface/dag.go @@ -0,0 +1,13 @@ +package iface + +import ( + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" +) + +// APIDagService extends ipld.DAGService +type APIDagService interface { + ipld.DAGService + + // Pinning returns special NodeAdder which recursively pins added nodes + Pinning() ipld.NodeAdder +}