-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4471 from ipfs/feat/coreapi/dag
RFC: coreapi.Dag
- Loading branch information
Showing
6 changed files
with
330 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package coreapi | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"io" | ||
|
||
gopath "path" | ||
|
||
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" | ||
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" | ||
coredag "github.com/ipfs/go-ipfs/core/coredag" | ||
|
||
cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" | ||
) | ||
|
||
type DagAPI struct { | ||
*CoreAPI | ||
*caopts.DagOptions | ||
} | ||
|
||
func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPutOption) (coreiface.Path, error) { | ||
settings, err := caopts.DagPutOptions(opts...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
codec, ok := cid.CodecToStr[settings.Codec] | ||
if !ok { | ||
return nil, fmt.Errorf("invalid codec %d", settings.Codec) | ||
} | ||
|
||
nds, err := coredag.ParseInputs(settings.InputEnc, codec, src, settings.MhType, settings.MhLength) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if len(nds) == 0 { | ||
return nil, fmt.Errorf("no node returned from ParseInputs") | ||
} | ||
|
||
_, err = api.node.DAG.Add(nds[0]) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return ParseCid(nds[0].Cid()), nil | ||
} | ||
|
||
func (api *DagAPI) Get(ctx context.Context, path coreiface.Path) (coreiface.Node, error) { | ||
return api.core().ResolveNode(ctx, path) | ||
} | ||
|
||
func (api *DagAPI) Tree(ctx context.Context, p coreiface.Path, opts ...caopts.DagTreeOption) ([]coreiface.Path, error) { | ||
settings, err := caopts.DagTreeOptions(opts...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
n, err := api.Get(ctx, p) | ||
if err != nil { | ||
return nil, err | ||
} | ||
paths := n.Tree("", settings.Depth) | ||
out := make([]coreiface.Path, len(paths)) | ||
for n, p2 := range paths { | ||
out[n], err = ParsePath(gopath.Join(p.String(), p2)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return out, nil | ||
} | ||
|
||
func (api *DagAPI) core() coreiface.CoreAPI { | ||
return api.CoreAPI | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package coreapi_test | ||
|
||
import ( | ||
"context" | ||
"path" | ||
"strings" | ||
"testing" | ||
|
||
coreapi "github.com/ipfs/go-ipfs/core/coreapi" | ||
|
||
mh "gx/ipfs/QmYeKnKpubCMRiq3PGZcTREErthbb5Q9cXsCoSkD9bjEBd/go-multihash" | ||
) | ||
|
||
var ( | ||
treeExpected = map[string]struct{}{ | ||
"a": {}, | ||
"b": {}, | ||
"c": {}, | ||
"c/d": {}, | ||
"c/e": {}, | ||
} | ||
) | ||
|
||
func TestPut(t *testing.T) { | ||
ctx := context.Background() | ||
_, api, err := makeAPI(ctx) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`)) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if res.Cid().String() != "zdpuAqckYF3ToF3gcJNxPZXmnmGuXd3gxHCXhq81HGxBejEvv" { | ||
t.Errorf("got wrong cid: %s", res.Cid().String()) | ||
} | ||
} | ||
|
||
func TestPutWithHash(t *testing.T) { | ||
ctx := context.Background() | ||
_, api, err := makeAPI(ctx) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
res, err := api.Dag().Put(ctx, strings.NewReader(`"Hello"`), api.Dag().WithHash(mh.ID, -1)) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if res.Cid().String() != "z5hRLNd2sv4z1c" { | ||
t.Errorf("got wrong cid: %s", res.Cid().String()) | ||
} | ||
} | ||
|
||
func TestPath(t *testing.T) { | ||
ctx := context.Background() | ||
_, api, err := makeAPI(ctx) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
sub, err := api.Dag().Put(ctx, strings.NewReader(`"foo"`)) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
res, err := api.Dag().Put(ctx, strings.NewReader(`{"lnk": {"/": "`+sub.Cid().String()+`"}}`)) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
p, err := coreapi.ParsePath(path.Join(res.Cid().String(), "lnk")) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
nd, err := api.Dag().Get(ctx, p) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if nd.Cid().String() != sub.Cid().String() { | ||
t.Errorf("got unexpected cid %s, expected %s", nd.Cid().String(), sub.Cid().String()) | ||
} | ||
} | ||
|
||
func TestTree(t *testing.T) { | ||
ctx := context.Background() | ||
_, api, err := makeAPI(ctx) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
c, err := api.Dag().Put(ctx, strings.NewReader(`{"a": 123, "b": "foo", "c": {"d": 321, "e": 111}}`)) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
res, err := api.Dag().Get(ctx, c) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
lst := res.Tree("", -1) | ||
if len(lst) != len(treeExpected) { | ||
t.Errorf("tree length of %d doesn't match expected %d", len(lst), len(treeExpected)) | ||
} | ||
|
||
for _, ent := range lst { | ||
if _, ok := treeExpected[ent]; !ok { | ||
t.Errorf("unexpected tree entry %s", ent) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package options | ||
|
||
import ( | ||
"math" | ||
|
||
cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" | ||
) | ||
|
||
type DagPutSettings struct { | ||
InputEnc string | ||
Codec uint64 | ||
MhType uint64 | ||
MhLength int | ||
} | ||
|
||
type DagTreeSettings struct { | ||
Depth int | ||
} | ||
|
||
type DagPutOption func(*DagPutSettings) error | ||
type DagTreeOption func(*DagTreeSettings) error | ||
|
||
func DagPutOptions(opts ...DagPutOption) (*DagPutSettings, error) { | ||
options := &DagPutSettings{ | ||
InputEnc: "json", | ||
Codec: cid.DagCBOR, | ||
MhType: math.MaxUint64, | ||
MhLength: -1, | ||
} | ||
|
||
for _, opt := range opts { | ||
err := opt(options) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
return options, nil | ||
} | ||
|
||
func DagTreeOptions(opts ...DagTreeOption) (*DagTreeSettings, error) { | ||
options := &DagTreeSettings{ | ||
Depth: -1, | ||
} | ||
|
||
for _, opt := range opts { | ||
err := opt(options) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
return options, nil | ||
} | ||
|
||
type DagOptions struct{} | ||
|
||
func (api *DagOptions) WithInputEnc(enc string) DagPutOption { | ||
return func(settings *DagPutSettings) error { | ||
settings.InputEnc = enc | ||
return nil | ||
} | ||
} | ||
|
||
func (api *DagOptions) WithCodec(codec uint64) DagPutOption { | ||
return func(settings *DagPutSettings) error { | ||
settings.Codec = codec | ||
return nil | ||
} | ||
} | ||
|
||
func (api *DagOptions) WithHash(mhType uint64, mhLen int) DagPutOption { | ||
return func(settings *DagPutSettings) error { | ||
settings.MhType = mhType | ||
settings.MhLength = mhLen | ||
return nil | ||
} | ||
} | ||
|
||
func (api *DagOptions) WithDepth(depth int) DagTreeOption { | ||
return func(settings *DagTreeSettings) error { | ||
settings.Depth = depth | ||
return nil | ||
} | ||
} |
Oops, something went wrong.