Commit ae949e3a authored by Łukasz Magiera's avatar Łukasz Magiera

coreapi: Object api review

License: MIT
Signed-off-by: default avatarŁukasz Magiera <magik6k@gmail.com>
parent 529f8472
......@@ -42,7 +42,7 @@ func (api *CoreAPI) Key() coreiface.KeyAPI {
}
func (api *CoreAPI) Object() coreiface.ObjectAPI {
return (*ObjectAPI)(api)
return &ObjectAPI{api, nil}
}
// ResolveNode resolves the path `p` using Unixfx resolver, gets and returns the
......
......@@ -193,14 +193,18 @@ type KeyAPI interface {
//TODO: Should this use paths instead of cids?
type ObjectAPI interface {
New(ctx context.Context) (Node, error)
Put(context.Context, Node) error
New(context.Context, ...options.ObjectNewOption) (Node, error)
WithType(string) options.ObjectNewOption
Put(context.Context, Node) (Path, 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)
......
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
}
}
......@@ -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/QmNwUEK7QbwSqyKBu3mMtToo8SUc6wQJ7gdZq4gGGJqfnf/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
func (api *ObjectAPI) Put(context.Context, coreiface.Node) (coreiface.Path, error) {
return nil, errors.New("todo") // TODO: implement using dag api.
}
func (api *ObjectAPI) Get(ctx context.Context, path coreiface.Path) (coreiface.Node, error) {
......@@ -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
}
......@@ -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 {
......@@ -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 {
......@@ -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
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment