github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/transform/startf/ds/bound.go (about) 1 package ds 2 3 import ( 4 "fmt" 5 6 "github.com/qri-io/dataset" 7 "github.com/qri-io/starlib/dataframe" 8 "go.starlark.net/starlark" 9 ) 10 11 // BoundDataset represents the datset a transform script is bound to 12 type BoundDataset struct { 13 frozen bool 14 commitCalled bool 15 latest *dataset.Dataset 16 outconf *dataframe.OutputConfig 17 onCommit func(ds *Dataset) error 18 load func(refstr string) (*Dataset, error) 19 } 20 21 // compile-time interface assertions 22 var ( 23 _ starlark.Value = (*BoundDataset)(nil) 24 _ starlark.HasAttrs = (*BoundDataset)(nil) 25 ) 26 27 // NewBoundDataset constructs a target dataset 28 func NewBoundDataset(latest *dataset.Dataset, outconf *dataframe.OutputConfig, onCommit func(ds *Dataset) error) *BoundDataset { 29 return &BoundDataset{latest: latest, onCommit: onCommit, outconf: outconf} 30 } 31 32 // String returns the Dataset as a string 33 func (b *BoundDataset) String() string { return b.stringify() } 34 35 // Type returns a short string describing the value's type. 36 func (BoundDataset) Type() string { return fmt.Sprintf("%s.BoundDataset", "dataset") } 37 38 // Freeze renders Dataset immutable. 39 func (b *BoundDataset) Freeze() { b.frozen = true } 40 41 // Hash cannot be used with Dataset 42 func (b *BoundDataset) Hash() (uint32, error) { 43 return 0, fmt.Errorf("unhashable: %s", b.Type()) 44 } 45 46 // Truth converts the dataset into a bool 47 func (b *BoundDataset) Truth() starlark.Bool { return true } 48 49 // Attr gets a value for a string attribute 50 func (b *BoundDataset) Attr(name string) (starlark.Value, error) { 51 return builtinAttr(b, name, boundDatasetMethods) 52 } 53 54 // AttrNames lists available attributes 55 func (b *BoundDataset) AttrNames() []string { 56 return builtinAttrNames(boundDatasetMethods) 57 } 58 59 func (b *BoundDataset) stringify() string { return "<BoundDataset>" } 60 61 // methods defined on the history object 62 var boundDatasetMethods = map[string]*starlark.Builtin{ 63 "latest": starlark.NewBuiltin("latest", head), 64 "commit": starlark.NewBuiltin("commit", commit), 65 } 66 67 func head(thread *starlark.Thread, builtin *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 68 self := builtin.Receiver().(*BoundDataset) 69 return NewDataset(self.latest, self.outconf), nil 70 } 71 72 func commit(thread *starlark.Thread, builtin *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 73 self := builtin.Receiver().(*BoundDataset) 74 if self.commitCalled { 75 return nil, fmt.Errorf("commit can only be called once in a transform script") 76 } 77 starDs := &Dataset{} 78 if err := starlark.UnpackArgs("commit", args, kwargs, "ds", starDs); err != nil { 79 return starlark.None, err 80 } 81 if self.onCommit != nil { 82 if err := self.onCommit(starDs); err != nil { 83 return starlark.None, err 84 } 85 } 86 87 self.commitCalled = true 88 return starlark.None, nil 89 }