github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/diff/diff_source.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package diff 16 17 import ( 18 "errors" 19 "io" 20 "time" 21 22 "github.com/dolthub/dolt/go/libraries/doltcore/row" 23 "github.com/dolthub/dolt/go/libraries/doltcore/rowconv" 24 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 25 "github.com/dolthub/dolt/go/libraries/doltcore/table/pipeline" 26 "github.com/dolthub/dolt/go/store/types" 27 ) 28 29 const ( 30 From = "from" 31 To = "to" 32 ) 33 34 type RowDiffSource struct { 35 ad RowDiffer 36 joiner *rowconv.Joiner 37 oldRowConv *rowconv.RowConverter 38 newRowConv *rowconv.RowConverter 39 } 40 41 func NewRowDiffSource(ad RowDiffer, joiner *rowconv.Joiner) *RowDiffSource { 42 return &RowDiffSource{ 43 ad, 44 joiner, 45 rowconv.IdentityConverter, 46 rowconv.IdentityConverter, 47 } 48 } 49 50 func (rdRd *RowDiffSource) AddInputRowConversion(oldConv, newConv *rowconv.RowConverter) { 51 rdRd.oldRowConv = oldConv 52 rdRd.newRowConv = newConv 53 } 54 55 // GetSchema gets the schema of the rows that this reader will return 56 func (rdRd *RowDiffSource) GetSchema() schema.Schema { 57 return rdRd.joiner.GetSchema() 58 } 59 60 // NextDiff reads a row from a table. If there is a bad row the returned error will be non nil, and callin IsBadRow(err) 61 // will be return true. This is a potentially non-fatal error and callers can decide if they want to continue on a bad row, or fail. 62 func (rdRd *RowDiffSource) NextDiff() (row.Row, pipeline.ImmutableProperties, error) { 63 diffs, hasMore, err := rdRd.ad.GetDiffs(1, time.Second) 64 if err != nil { 65 return nil, pipeline.ImmutableProperties{}, err 66 } 67 68 if len(diffs) == 0 { 69 if !hasMore { 70 return nil, pipeline.NoProps, io.EOF 71 } 72 return nil, pipeline.NoProps, errors.New("timeout") 73 } 74 75 if len(diffs) != 1 { 76 panic("only a single diff requested, multiple returned. bug in AsyncDiffer") 77 } 78 79 d := diffs[0] 80 rows := make(map[string]row.Row) 81 if d.OldValue != nil { 82 sch := rdRd.joiner.SchemaForName(From) 83 if !rdRd.oldRowConv.IdentityConverter { 84 sch = rdRd.oldRowConv.SrcSch 85 } 86 87 oldRow, err := row.FromNoms(sch, d.KeyValue.(types.Tuple), d.OldValue.(types.Tuple)) 88 89 if err != nil { 90 return nil, pipeline.ImmutableProperties{}, err 91 } 92 93 rows[From], err = rdRd.oldRowConv.Convert(oldRow) 94 95 if err != nil { 96 return nil, pipeline.NoProps, err 97 } 98 } 99 100 if d.NewValue != nil { 101 sch := rdRd.joiner.SchemaForName(To) 102 if !rdRd.newRowConv.IdentityConverter { 103 sch = rdRd.newRowConv.SrcSch 104 } 105 106 newRow, err := row.FromNoms(sch, d.KeyValue.(types.Tuple), d.NewValue.(types.Tuple)) 107 108 if err != nil { 109 return nil, pipeline.ImmutableProperties{}, err 110 } 111 112 rows[To], err = rdRd.newRowConv.Convert(newRow) 113 114 if err != nil { 115 return nil, pipeline.NoProps, err 116 } 117 } 118 119 joinedRow, err := rdRd.joiner.Join(rows) 120 121 if err != nil { 122 return nil, pipeline.ImmutableProperties{}, err 123 } 124 125 return joinedRow, pipeline.ImmutableProperties{}, nil 126 } 127 128 // Close should release resources being held 129 func (rdRd *RowDiffSource) Close() error { 130 rdRd.ad.Close() 131 return nil 132 }