Skip to content

Commit

Permalink
coreapi: Object api review
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
  • Loading branch information
magik6k committed Dec 22, 2017
1 parent 709b3c4 commit 0c5d07c
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 20 deletions.
2 changes: 1 addition & 1 deletion core/coreapi/coreapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (api *CoreAPI) Unixfs() coreiface.UnixfsAPI {
}

func (api *CoreAPI) Object() coreiface.ObjectAPI {
return (*ObjectAPI)(api)
return &ObjectAPI{api, nil}
}

func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) {
Expand Down
10 changes: 8 additions & 2 deletions core/coreapi/interface/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"errors"
"io"

options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"

cid "gx/ipfs/QmNp85zy9RLrQ5oQD4hPyS39ezrrXpcaa7R4Y9kxdWQLLQ/go-cid"
ipld "gx/ipfs/QmPN7cwmpcc4DWXb4KTB9dNAJgjuPY69h3npsMfhRrQL9c/go-ipld-format"
)
Expand Down Expand Up @@ -40,14 +42,18 @@ type UnixfsAPI interface {

//TODO: Should this use paths instead of cids?
type ObjectAPI interface {
New(ctx context.Context) (Node, error)
New(context.Context, ...options.ObjectNewOption) (Node, error)
WithType(string) options.ObjectNewOption

Put(context.Context, Node) error
Get(context.Context, Path) (Node, error)
Data(context.Context, Path) (io.Reader, error)
Links(context.Context, Path) ([]*Link, error)
Stat(context.Context, Path) (*ObjectStat, error)

AddLink(ctx context.Context, base Path, name string, child Path, create bool) (Node, error) //TODO: make create optional
AddLink(ctx context.Context, base Path, name string, child Path, opts ...options.ObjectAddLinkOption) (Node, error)
WithCreate(create bool) options.ObjectAddLinkOption

RmLink(context.Context, Path, string) (Node, error)
AppendData(context.Context, Path, io.Reader) (Node, error)
SetData(context.Context, Path, io.Reader) (Node, error)
Expand Down
56 changes: 56 additions & 0 deletions core/coreapi/interface/options/object.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package options

type ObjectNewSettings struct {
Type string
}

type ObjectAddLinkSettings struct {
Create bool
}

type ObjectNewOption func(*ObjectNewSettings) error
type ObjectAddLinkOption func(*ObjectAddLinkSettings) error

func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) {
options := &ObjectNewSettings{
Type: "empty",
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}
return options, nil
}

func ObjectAddLinkOptions(opts ...ObjectAddLinkOption) (*ObjectAddLinkSettings, error) {
options := &ObjectAddLinkSettings{
Create: false,
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}
return options, nil
}

type ObjectOptions struct{}

func (api *ObjectOptions) WithType(t string) ObjectNewOption {
return func(settings *ObjectNewSettings) error {
settings.Type = t
return nil
}
}

func (api *ObjectOptions) WithCreate(create bool) ObjectAddLinkOption {
return func(settings *ObjectAddLinkSettings) error {
settings.Create = create
return nil
}
}
56 changes: 39 additions & 17 deletions core/coreapi/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,44 @@ import (
"io"
"io/ioutil"

"github.com/ipfs/go-ipfs/merkledag/utils"
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
dagutils "github.com/ipfs/go-ipfs/merkledag/utils"

coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
dag "github.com/ipfs/go-ipfs/merkledag"
ft "github.com/ipfs/go-ipfs/unixfs"

node "gx/ipfs/QmPN7cwmpcc4DWXb4KTB9dNAJgjuPY69h3npsMfhRrQL9c/go-ipld-format"
)

type ObjectAPI CoreAPI
type ObjectAPI struct {
*CoreAPI
*caopts.ObjectOptions
}

func (api *ObjectAPI) New(ctx context.Context) (coreiface.Node, error) {
node := new(dag.ProtoNode)
func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (coreiface.Node, error) {
options, err := caopts.ObjectNewOptions(opts...)
if err != nil {
return nil, err
}

_, err := api.node.DAG.Add(node)
var n node.Node
switch options.Type {
case "empty":
n = new(dag.ProtoNode)
case "unixfs-dir":
n = ft.EmptyDirNode()
}

_, err = api.node.DAG.Add(n)
if err != nil {
return nil, err
}
return node, nil
return n, nil
}

func (api *ObjectAPI) Put(context.Context, coreiface.Node) error {
return errors.New("todo") // TODO: what should this method take? Should we just redir to dag-put?f
return errors.New("todo") // TODO: implement using dag api.
}

func (api *ObjectAPI) Get(ctx context.Context, path coreiface.Path) (coreiface.Node, error) {
Expand Down Expand Up @@ -86,8 +103,13 @@ func (api *ObjectAPI) Stat(ctx context.Context, path coreiface.Path) (*coreiface
return out, nil
}

func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name string, child coreiface.Path, create bool) (coreiface.Node, error) {
rootNd, err := api.core().ResolveNode(ctx, base)
func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name string, child coreiface.Path, opts ...caopts.ObjectAddLinkOption) (coreiface.Node, error) {
options, err := caopts.ObjectAddLinkOptions(opts...)
if err != nil {
return nil, err
}

baseNd, err := api.core().ResolveNode(ctx, base)
if err != nil {
return nil, err
}
Expand All @@ -97,17 +119,17 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name str
return nil, err
}

rootPb, ok := rootNd.(*dag.ProtoNode)
basePb, ok := baseNd.(*dag.ProtoNode)
if !ok {
return nil, dag.ErrNotProtobuf
}

var createfunc func() *dag.ProtoNode
if create {
if options.Create {
createfunc = ft.EmptyDirNode
}

e := dagutils.NewDagEditor(rootPb, api.node.DAG)
e := dagutils.NewDagEditor(basePb, api.node.DAG)

err = e.InsertNodeAtPath(ctx, name, childNd, createfunc)
if err != nil {
Expand All @@ -122,18 +144,18 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name str
return nnode, nil
}

func (api *ObjectAPI) RmLink(ctx context.Context, root coreiface.Path, link string) (coreiface.Node, error) {
rootNd, err := api.core().ResolveNode(ctx, root)
func (api *ObjectAPI) RmLink(ctx context.Context, base coreiface.Path, link string) (coreiface.Node, error) {
baseNd, err := api.core().ResolveNode(ctx, base)
if err != nil {
return nil, err
}

rootPb, ok := rootNd.(*dag.ProtoNode)
basePb, ok := baseNd.(*dag.ProtoNode)
if !ok {
return nil, dag.ErrNotProtobuf
}

e := dagutils.NewDagEditor(rootPb, api.node.DAG)
e := dagutils.NewDagEditor(basePb, api.node.DAG)

err = e.RmLink(ctx, link)
if err != nil {
Expand Down Expand Up @@ -186,5 +208,5 @@ func (api *ObjectAPI) patchData(ctx context.Context, path coreiface.Path, r io.R
}

func (api *ObjectAPI) core() coreiface.CoreAPI {
return (*CoreAPI)(api)
return api.CoreAPI
}

0 comments on commit 0c5d07c

Please sign in to comment.