Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit c356d0d

Browse files
fabiobozzohacdias
andauthored
feat: add DagImport method (#287)
Co-authored-by: Henrique Dias <[email protected]>
1 parent 82a4237 commit c356d0d

File tree

8 files changed

+304
-80
lines changed

8 files changed

+304
-80
lines changed

dag.go

Lines changed: 112 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,41 @@ package shell
33
import (
44
"bytes"
55
"context"
6+
"encoding/json"
67
"fmt"
78
"io"
89
"strings"
910

10-
"github.com/ipfs/go-ipfs-api/options"
1111
files "github.com/ipfs/go-ipfs-files"
12+
13+
"github.com/ipfs/go-ipfs-api/options"
1214
)
1315

16+
type DagPutOutput struct {
17+
Cid struct {
18+
Target string `json:"/"`
19+
}
20+
}
21+
22+
type DagImportRoot struct {
23+
Root struct {
24+
Cid struct {
25+
Value string `json:"/"`
26+
}
27+
}
28+
Stats *DagImportStats `json:"Stats,omitempty"`
29+
}
30+
31+
type DagImportStats struct {
32+
BlockBytesCount uint64
33+
BlockCount uint64
34+
}
35+
36+
type DagImportOutput struct {
37+
Roots []DagImportRoot
38+
Stats *DagImportStats
39+
}
40+
1441
func (s *Shell) DagGet(ref string, out interface{}) error {
1542
return s.Request("dag/get", ref).Exec(context.Background(), out)
1643
}
@@ -25,34 +52,103 @@ func (s *Shell) DagPutWithOpts(data interface{}, opts ...options.DagPutOption) (
2552
return "", err
2653
}
2754

55+
fileReader, err := dagToFilesReader(data)
56+
if err != nil {
57+
return "", err
58+
}
59+
60+
var out DagPutOutput
61+
62+
return out.Cid.Target, s.
63+
Request("dag/put").
64+
Option("input-codec", cfg.InputCodec).
65+
Option("store-codec", cfg.StoreCodec).
66+
Option("pin", cfg.Pin).
67+
Option("hash", cfg.Hash).
68+
Body(fileReader).
69+
Exec(context.Background(), &out)
70+
}
71+
72+
// DagImport imports the contents of .car files (with default parameters)
73+
func (s *Shell) DagImport(data interface{}, silent, stats bool) (*DagImportOutput, error) {
74+
return s.DagImportWithOpts(data, options.Dag.Silent(silent), options.Dag.Stats(stats))
75+
}
76+
77+
// DagImportWithOpts imports the contents of .car files
78+
func (s *Shell) DagImportWithOpts(data interface{}, opts ...options.DagImportOption) (*DagImportOutput, error) {
79+
cfg, err := options.DagImportOptions(opts...)
80+
if err != nil {
81+
return nil, err
82+
}
83+
84+
fileReader, err := dagToFilesReader(data)
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
res, err := s.Request("dag/import").
90+
Option("pin-roots", cfg.PinRoots).
91+
Option("silent", cfg.Silent).
92+
Option("stats", cfg.Stats).
93+
Option("allow-big-block", cfg.AllowBigBlock).
94+
Body(fileReader).
95+
Send(context.Background())
96+
if err != nil {
97+
return nil, err
98+
}
99+
defer res.Close()
100+
101+
if res.Error != nil {
102+
return nil, res.Error
103+
}
104+
105+
if cfg.Silent {
106+
return nil, nil
107+
}
108+
109+
out := DagImportOutput{
110+
Roots: []DagImportRoot{},
111+
}
112+
113+
dec := json.NewDecoder(res.Output)
114+
115+
for {
116+
var root DagImportRoot
117+
err := dec.Decode(&root)
118+
if err == io.EOF {
119+
break
120+
}
121+
122+
if root.Stats != nil {
123+
out.Stats = root.Stats
124+
125+
break
126+
}
127+
128+
out.Roots = append(out.Roots, root)
129+
}
130+
131+
return &out, err
132+
}
133+
134+
func dagToFilesReader(data interface{}) (*files.MultiFileReader, error) {
28135
var r io.Reader
29136
switch data := data.(type) {
137+
case *files.MultiFileReader:
138+
return data, nil
30139
case string:
31140
r = strings.NewReader(data)
32141
case []byte:
33142
r = bytes.NewReader(data)
34143
case io.Reader:
35144
r = data
36145
default:
37-
return "", fmt.Errorf("cannot current handle putting values of type %T", data)
146+
return nil, fmt.Errorf("values of type %T cannot be handled as DAG input", data)
38147
}
39148

40149
fr := files.NewReaderFile(r)
41150
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
42151
fileReader := files.NewMultiFileReader(slf, true)
43152

44-
var out struct {
45-
Cid struct {
46-
Target string `json:"/"`
47-
}
48-
}
49-
50-
return out.Cid.Target, s.
51-
Request("dag/put").
52-
Option("input-codec", cfg.InputCodec).
53-
Option("store-codec", cfg.StoreCodec).
54-
Option("pin", cfg.Pin).
55-
Option("hash", cfg.Hash).
56-
Body(fileReader).
57-
Exec(context.Background(), &out)
153+
return fileReader, nil
58154
}

options/dag.go

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,5 @@
11
package options
22

3-
// DagPutSettings is a set of DagPut options.
4-
type DagPutSettings struct {
5-
InputCodec string
6-
StoreCodec string
7-
Pin string
8-
Hash string
9-
}
10-
11-
// DagPutOption is a single DagPut option.
12-
type DagPutOption func(opts *DagPutSettings) error
13-
14-
// DagPutOptions applies the given options to a DagPutSettings instance.
15-
func DagPutOptions(opts ...DagPutOption) (*DagPutSettings, error) {
16-
options := &DagPutSettings{
17-
InputCodec: "dag-json",
18-
StoreCodec: "dag-cbor",
19-
Pin: "false",
20-
Hash: "sha2-256",
21-
}
22-
23-
for _, opt := range opts {
24-
err := opt(options)
25-
if err != nil {
26-
return nil, err
27-
}
28-
}
29-
return options, nil
30-
}
31-
323
type dagOpts struct{}
334

345
var Dag dagOpts
35-
36-
// Pin is an option for Dag.Put which specifies whether to pin the added
37-
// dags. Default is "false".
38-
func (dagOpts) Pin(pin string) DagPutOption {
39-
return func(opts *DagPutSettings) error {
40-
opts.Pin = pin
41-
return nil
42-
}
43-
}
44-
45-
// InputCodec is an option for Dag.Put which specifies the input encoding of the
46-
// data. Default is "dag-json".
47-
func (dagOpts) InputCodec(codec string) DagPutOption {
48-
return func(opts *DagPutSettings) error {
49-
opts.InputCodec = codec
50-
return nil
51-
}
52-
}
53-
54-
// StoreCodec is an option for Dag.Put which specifies the codec that the stored
55-
// object will be encoded with. Default is "dag-cbor".
56-
func (dagOpts) StoreCodec(codec string) DagPutOption {
57-
return func(opts *DagPutSettings) error {
58-
opts.StoreCodec = codec
59-
return nil
60-
}
61-
}
62-
63-
// Hash is an option for Dag.Put which specifies the hash function to use
64-
func (dagOpts) Hash(hash string) DagPutOption {
65-
return func(opts *DagPutSettings) error {
66-
opts.Hash = hash
67-
return nil
68-
}
69-
}

options/dag_import.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package options
2+
3+
// DagImportSettings is a set of DagImport options.
4+
type DagImportSettings struct {
5+
PinRoots bool
6+
Silent bool
7+
Stats bool
8+
AllowBigBlock bool
9+
}
10+
11+
// DagImportOption is a single DagImport option.
12+
type DagImportOption func(opts *DagImportSettings) error
13+
14+
// DagImportOptions applies the given options to a DagImportSettings instance.
15+
func DagImportOptions(opts ...DagImportOption) (*DagImportSettings, error) {
16+
options := &DagImportSettings{
17+
PinRoots: true,
18+
Silent: false,
19+
Stats: false,
20+
AllowBigBlock: false,
21+
}
22+
23+
for _, opt := range opts {
24+
err := opt(options)
25+
if err != nil {
26+
return nil, err
27+
}
28+
}
29+
30+
return options, nil
31+
}
32+
33+
// PinRoots is an option for Dag.Import which specifies whether to
34+
// pin the optional roots listed in the .car headers after importing.
35+
// Default is true.
36+
func (dagOpts) PinRoots(pinRoots bool) DagImportOption {
37+
return func(opts *DagImportSettings) error {
38+
opts.PinRoots = pinRoots
39+
return nil
40+
}
41+
}
42+
43+
// Silent is an option for Dag.Import which specifies whether to
44+
// return any output or not.
45+
// Default is false.
46+
func (dagOpts) Silent(silent bool) DagImportOption {
47+
return func(opts *DagImportSettings) error {
48+
opts.Silent = silent
49+
return nil
50+
}
51+
}
52+
53+
// Stats is an option for Dag.Import which specifies whether to
54+
// return stats about the import operation.
55+
// Default is false.
56+
func (dagOpts) Stats(stats bool) DagImportOption {
57+
return func(opts *DagImportSettings) error {
58+
opts.Stats = stats
59+
return nil
60+
}
61+
}
62+
63+
// AllowBigBlock is an option for Dag.Import which disables block size check
64+
// and allow creation of blocks bigger than 1MiB.
65+
// WARNING: such blocks won't be transferable over the standard bitswap.
66+
// Default is false.
67+
func (dagOpts) AllowBigBlock(allowBigBlock bool) DagImportOption {
68+
return func(opts *DagImportSettings) error {
69+
opts.AllowBigBlock = allowBigBlock
70+
return nil
71+
}
72+
}

options/dag_put.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package options
2+
3+
// DagPutSettings is a set of Dag options.
4+
type DagPutSettings struct {
5+
InputCodec string
6+
StoreCodec string
7+
Pin string
8+
Hash string
9+
}
10+
11+
// DagPutOption is a single Dag option.
12+
type DagPutOption func(opts *DagPutSettings) error
13+
14+
// DagPutOptions applies the given options to a DagPutSettings instance.
15+
func DagPutOptions(opts ...DagPutOption) (*DagPutSettings, error) {
16+
options := &DagPutSettings{
17+
InputCodec: "dag-json",
18+
StoreCodec: "dag-cbor",
19+
Pin: "false",
20+
Hash: "sha2-256",
21+
}
22+
23+
for _, opt := range opts {
24+
err := opt(options)
25+
if err != nil {
26+
return nil, err
27+
}
28+
}
29+
return options, nil
30+
}
31+
32+
// Pin is an option for Dag.Put which specifies whether to pin the added
33+
// dags. Default is "false".
34+
func (dagOpts) Pin(pin string) DagPutOption {
35+
return func(opts *DagPutSettings) error {
36+
opts.Pin = pin
37+
return nil
38+
}
39+
}
40+
41+
// InputCodec is an option for Dag.Put which specifies the input encoding of the
42+
// data. Default is "dag-json".
43+
func (dagOpts) InputCodec(codec string) DagPutOption {
44+
return func(opts *DagPutSettings) error {
45+
opts.InputCodec = codec
46+
return nil
47+
}
48+
}
49+
50+
// StoreCodec is an option for Dag.Put which specifies the codec that the stored
51+
// object will be encoded with. Default is "dag-cbor".
52+
func (dagOpts) StoreCodec(codec string) DagPutOption {
53+
return func(opts *DagPutSettings) error {
54+
opts.StoreCodec = codec
55+
return nil
56+
}
57+
}
58+
59+
// Hash is an option for Dag.Put which specifies the hash function to use
60+
func (dagOpts) Hash(hash string) DagPutOption {
61+
return func(opts *DagPutSettings) error {
62+
opts.Hash = hash
63+
return nil
64+
}
65+
}

0 commit comments

Comments
 (0)