|
1 | 1 | package httpapi
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
4 | 5 | "context"
|
5 | 6 | "fmt"
|
6 |
| - "io" |
7 |
| - "math" |
| 7 | + "io/ioutil" |
| 8 | + "sync" |
8 | 9 |
|
9 | 10 | "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
10 |
| - caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" |
| 11 | + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" |
11 | 12 |
|
| 13 | + "github.com/ipfs/go-block-format" |
12 | 14 | "github.com/ipfs/go-cid"
|
13 | 15 | "github.com/ipfs/go-ipld-format"
|
14 |
| - mh "github.com/multiformats/go-multihash" |
15 | 16 | )
|
16 | 17 |
|
17 |
| -type DagAPI HttpApi |
| 18 | +type HttpDagServ HttpApi |
18 | 19 |
|
19 |
| -func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPutOption) (iface.ResolvedPath, error) { |
20 |
| - options, err := caopts.DagPutOptions(opts...) |
| 20 | +func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) { |
| 21 | + r, err := api.core().Block().Get(ctx, iface.IpldPath(c)) |
21 | 22 | if err != nil {
|
22 | 23 | return nil, err
|
23 | 24 | }
|
24 | 25 |
|
25 |
| - codec, ok := cid.CodecToStr[options.Codec] |
26 |
| - if !ok { |
27 |
| - return nil, fmt.Errorf("unknowm codec %d", options.MhType) |
| 26 | + data, err := ioutil.ReadAll(r) |
| 27 | + if err != nil { |
| 28 | + return nil, err |
28 | 29 | }
|
29 | 30 |
|
30 |
| - if options.MhLength != -1 { |
31 |
| - return nil, fmt.Errorf("setting hash len is not supported yet") |
| 31 | + blk, err := blocks.NewBlockWithCid(data, c) |
| 32 | + if err != nil { |
| 33 | + return nil, err |
32 | 34 | }
|
33 | 35 |
|
34 |
| - var out struct { |
35 |
| - Cid cid.Cid |
| 36 | + return format.DefaultBlockDecoder.Decode(blk) |
| 37 | +} |
| 38 | + |
| 39 | +func (api *HttpDagServ) GetMany(ctx context.Context, cids []cid.Cid) <-chan *format.NodeOption { |
| 40 | + out := make(chan *format.NodeOption) |
| 41 | + wg := sync.WaitGroup{} |
| 42 | + wg.Add(len(cids)) |
| 43 | + |
| 44 | + for _, c := range cids { |
| 45 | + // TODO: Consider limiting concurrency of this somehow |
| 46 | + go func() { |
| 47 | + defer wg.Done() |
| 48 | + n, err := api.Get(ctx, c) |
| 49 | + |
| 50 | + select { |
| 51 | + case out <- &format.NodeOption{Node: n, Err: err}: |
| 52 | + case <-ctx.Done(): |
| 53 | + } |
| 54 | + }() |
36 | 55 | }
|
37 |
| - req := api.core().request("dag/put"). |
38 |
| - Option("format", codec). |
39 |
| - Option("input-enc", options.InputEnc) |
40 |
| - |
41 |
| - if options.MhType != math.MaxUint64 { |
42 |
| - mht, ok := mh.Codes[options.MhType] |
43 |
| - if !ok { |
44 |
| - return nil, fmt.Errorf("unknowm mhType %d", options.MhType) |
45 |
| - } |
46 |
| - req.Option("hash", mht) |
| 56 | + return out |
| 57 | +} |
| 58 | + |
| 59 | +func (api *HttpDagServ) Add(ctx context.Context, nd format.Node) error { |
| 60 | + c := nd.Cid() |
| 61 | + prefix := c.Prefix() |
| 62 | + format := cid.CodecToStr[prefix.Codec] |
| 63 | + if prefix.Version == 0 { |
| 64 | + format = "v0" |
47 | 65 | }
|
48 | 66 |
|
49 |
| - err = req.FileBody(src).Exec(ctx, &out) |
| 67 | + stat, err := api.core().Block().Put(ctx, bytes.NewReader(nd.RawData()), |
| 68 | + options.Block.Hash(prefix.MhType, prefix.MhLength), options.Block.Format(format)) |
50 | 69 | if err != nil {
|
51 |
| - return nil, err |
| 70 | + return err |
52 | 71 | }
|
53 |
| - |
54 |
| - return iface.IpldPath(out.Cid), nil |
| 72 | + if !stat.Path().Cid().Equals(c) { |
| 73 | + return fmt.Errorf("cids didn't match - local %s, remote %s", c.String(), stat.Path().Cid().String()) |
| 74 | + } |
| 75 | + return nil |
55 | 76 | }
|
56 | 77 |
|
57 |
| -func (api *DagAPI) Get(ctx context.Context, path iface.Path) (format.Node, error) { |
58 |
| - panic("implement me") |
| 78 | +func (api *HttpDagServ) AddMany(ctx context.Context, nds []format.Node) error { |
| 79 | + for _, nd := range nds { |
| 80 | + // TODO: optimize |
| 81 | + if err := api.Add(ctx, nd); err != nil { |
| 82 | + return err |
| 83 | + } |
| 84 | + } |
| 85 | + return nil |
59 | 86 | }
|
60 | 87 |
|
61 |
| -func (api *DagAPI) Tree(ctx context.Context, path iface.Path, opts ...caopts.DagTreeOption) ([]iface.Path, error) { |
62 |
| - panic("implement me") |
| 88 | +func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error { |
| 89 | + return api.core().Block().Rm(ctx, iface.IpldPath(c)) //TODO: should we force rm? |
63 | 90 | }
|
64 | 91 |
|
65 |
| -func (api *DagAPI) Batch(ctx context.Context) iface.DagBatch { |
66 |
| - panic("implement me") |
| 92 | +func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error { |
| 93 | + for _, c := range cids { |
| 94 | + // TODO: optimize |
| 95 | + if err := api.Remove(ctx, c); err != nil { |
| 96 | + return err |
| 97 | + } |
| 98 | + } |
| 99 | + return nil |
67 | 100 | }
|
68 | 101 |
|
69 |
| -func (api *DagAPI) core() *HttpApi { |
| 102 | +func (api *HttpDagServ) core() *HttpApi { |
70 | 103 | return (*HttpApi)(api)
|
71 | 104 | }
|
0 commit comments