mirror of
https://github.com/ipfs/kubo.git
synced 2025-05-17 23:16:11 +08:00
155 lines
3.6 KiB
Go
155 lines
3.6 KiB
Go
package coreapi
|
|
|
|
import (
|
|
"context"
|
|
|
|
dag "github.com/ipfs/boxo/ipld/merkledag"
|
|
"github.com/ipfs/boxo/ipld/merkledag/dagutils"
|
|
ft "github.com/ipfs/boxo/ipld/unixfs"
|
|
"github.com/ipfs/boxo/path"
|
|
coreiface "github.com/ipfs/kubo/core/coreiface"
|
|
caopts "github.com/ipfs/kubo/core/coreiface/options"
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/trace"
|
|
|
|
"github.com/ipfs/kubo/tracing"
|
|
)
|
|
|
|
type ObjectAPI CoreAPI
|
|
|
|
type Link struct {
|
|
Name, Hash string
|
|
Size uint64
|
|
}
|
|
|
|
type Node struct {
|
|
Links []Link
|
|
Data string
|
|
}
|
|
|
|
func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) {
|
|
ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AddLink", trace.WithAttributes(
|
|
attribute.String("base", base.String()),
|
|
attribute.String("name", name),
|
|
attribute.String("child", child.String()),
|
|
))
|
|
defer span.End()
|
|
|
|
options, err := caopts.ObjectAddLinkOptions(opts...)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
span.SetAttributes(attribute.Bool("create", options.Create))
|
|
|
|
baseNd, err := api.core().ResolveNode(ctx, base)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
|
|
childNd, err := api.core().ResolveNode(ctx, child)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
|
|
basePb, ok := baseNd.(*dag.ProtoNode)
|
|
if !ok {
|
|
return path.ImmutablePath{}, dag.ErrNotProtobuf
|
|
}
|
|
|
|
var createfunc func() *dag.ProtoNode
|
|
if options.Create {
|
|
createfunc = ft.EmptyDirNode
|
|
}
|
|
|
|
e := dagutils.NewDagEditor(basePb, api.dag)
|
|
|
|
err = e.InsertNodeAtPath(ctx, name, childNd, createfunc)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
|
|
nnode, err := e.Finalize(ctx, api.dag)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
|
|
return path.FromCid(nnode.Cid()), nil
|
|
}
|
|
|
|
func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) {
|
|
ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "RmLink", trace.WithAttributes(
|
|
attribute.String("base", base.String()),
|
|
attribute.String("link", link)),
|
|
)
|
|
defer span.End()
|
|
|
|
baseNd, err := api.core().ResolveNode(ctx, base)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
|
|
basePb, ok := baseNd.(*dag.ProtoNode)
|
|
if !ok {
|
|
return path.ImmutablePath{}, dag.ErrNotProtobuf
|
|
}
|
|
|
|
e := dagutils.NewDagEditor(basePb, api.dag)
|
|
|
|
err = e.RmLink(ctx, link)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
|
|
nnode, err := e.Finalize(ctx, api.dag)
|
|
if err != nil {
|
|
return path.ImmutablePath{}, err
|
|
}
|
|
|
|
return path.FromCid(nnode.Cid()), nil
|
|
}
|
|
|
|
func (api *ObjectAPI) Diff(ctx context.Context, before path.Path, after path.Path) ([]coreiface.ObjectChange, error) {
|
|
ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Diff", trace.WithAttributes(
|
|
attribute.String("before", before.String()),
|
|
attribute.String("after", after.String()),
|
|
))
|
|
defer span.End()
|
|
|
|
beforeNd, err := api.core().ResolveNode(ctx, before)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
afterNd, err := api.core().ResolveNode(ctx, after)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
changes, err := dagutils.Diff(ctx, api.dag, beforeNd, afterNd)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
out := make([]coreiface.ObjectChange, len(changes))
|
|
for i, change := range changes {
|
|
out[i] = coreiface.ObjectChange{
|
|
Type: coreiface.ChangeType(change.Type),
|
|
Path: change.Path,
|
|
}
|
|
|
|
if change.Before.Defined() {
|
|
out[i].Before = path.FromCid(change.Before)
|
|
}
|
|
|
|
if change.After.Defined() {
|
|
out[i].After = path.FromCid(change.After)
|
|
}
|
|
}
|
|
|
|
return out, nil
|
|
}
|
|
|
|
func (api *ObjectAPI) core() coreiface.CoreAPI {
|
|
return (*CoreAPI)(api)
|
|
}
|