forked from photon-storage/go-ipfs-car
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcar.go
128 lines (111 loc) · 2.5 KB
/
car.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package car
import (
"context"
"io"
"github.com/ipfs/go-cid"
carv1 "github.com/ipld/go-car"
carv2 "github.com/ipld/go-car/v2"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/storage/bsadapter"
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
)
// Builder builds a WriterTo from the given input source.
// The WriterTo can be used to output car format data to a io.Writer.
type Builder struct {
di *DataImporter
wt io.WriterTo
}
// NewBuilder creates a new car builder.
// Files processed by this builder are only stored in memory.
func NewBuilder() *Builder {
return &Builder{
di: NewDataImporter(),
}
}
// NewBuilder creates a new car builder, but files are backed by storage on the disk
// instead of in memory.
//
// path doesn't have to exist, but must be a directory if it does exist.
//
// It's up to the caller to remove the files stored under path once they are no longer
// using the Builder or the car structs it can build.
func NewBuilderDisk(path string) (*Builder, error) {
di, err := NewDataImporterDisk(path)
if err != nil {
return nil, err
}
return &Builder{
di: di,
}, nil
}
type CarV1 struct {
root cid.Cid
car *carv1.SelectiveCar
}
func (c *CarV1) Write(w io.Writer) error {
return c.car.Write(w)
}
func (c *CarV1) Root() cid.Cid {
return c.root
}
// Buildv1 builds a CarV1 for outputing car v1 format data.
func (b *Builder) Buildv1(
ctx context.Context,
input any,
opts ...ImportOption,
) (*CarV1, error) {
root, err := b.di.Import(ctx, input, opts...)
if err != nil {
return nil, err
}
car := carv1.NewSelectiveCar(
ctx,
b.di.Blockstore(),
[]carv1.Dag{
carv1.Dag{
Root: root,
Selector: selectorparse.CommonSelector_ExploreAllRecursively,
},
},
carv1.TraverseLinksOnlyOnce(),
)
return &CarV1{
root: root,
car: &car,
}, nil
}
type CarV2 struct {
root cid.Cid
io.WriterTo
}
func (c *CarV2) Root() cid.Cid {
return c.root
}
// Buildv2 builds a CarV2 for outputing car v2 format data.
func (b *Builder) Buildv2(
ctx context.Context,
input any,
opts ...ImportOption,
) (*CarV2, error) {
root, err := b.di.Import(ctx, input, opts...)
if err != nil {
return nil, err
}
ls := cidlink.DefaultLinkSystem()
ls.SetReadStorage(&bsadapter.Adapter{
Wrapped: b.di.Blockstore(),
})
w, err := carv2.NewSelectiveWriter(
ctx,
&ls,
root,
selectorparse.CommonSelector_ExploreAllRecursively,
)
if err != nil {
return nil, err
}
return &CarV2{
root: root,
WriterTo: w,
}, nil
}