github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/table/inmem_table_test.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 table 16 17 import ( 18 "context" 19 "io" 20 "testing" 21 22 "github.com/dolthub/dolt/go/libraries/doltcore/row" 23 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 24 "github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo" 25 "github.com/dolthub/dolt/go/store/types" 26 ) 27 28 const ( 29 nameTag uint64 = iota 30 ageTag 31 titleTag 32 greatTag 33 ) 34 35 var fields = schema.NewColCollection( 36 schema.Column{Name: "name", Tag: nameTag, Kind: types.StringKind, IsPartOfPK: true, TypeInfo: typeinfo.StringDefaultType, Constraints: nil}, 37 schema.Column{Name: "age", Tag: ageTag, Kind: types.UintKind, IsPartOfPK: true, TypeInfo: typeinfo.Uint64Type, Constraints: nil}, 38 schema.Column{Name: "title", Tag: titleTag, Kind: types.StringKind, IsPartOfPK: true, TypeInfo: typeinfo.StringDefaultType, Constraints: nil}, 39 schema.Column{Name: "is_great", Tag: greatTag, Kind: types.BoolKind, IsPartOfPK: true, TypeInfo: typeinfo.BoolType, Constraints: nil}, 40 ) 41 42 var rowSch = schema.MustSchemaFromCols(fields) 43 44 func mustRow(r row.Row, err error) row.Row { 45 if err != nil { 46 panic(err) 47 } 48 49 return r 50 } 51 52 // These are in noms-key-sorted order, since InMemoryTable.AppendRow sorts its rows. This should probably be done 53 // programatically instead of hard-coded. 54 var rows = []row.Row{ 55 mustRow(row.New(types.Format_Default, rowSch, row.TaggedValues{ 56 nameTag: types.String("Bill Billerson"), 57 ageTag: types.Uint(32), 58 titleTag: types.String("Senior Dufus"), 59 greatTag: types.Bool(true), 60 })), 61 mustRow(row.New(types.Format_Default, rowSch, row.TaggedValues{ 62 nameTag: types.String("John Johnson"), 63 ageTag: types.Uint(21), 64 titleTag: types.String("Intern Dufus"), 65 greatTag: types.Bool(true), 66 })), 67 mustRow(row.New(types.Format_Default, rowSch, row.TaggedValues{ 68 nameTag: types.String("Rob Robertson"), 69 ageTag: types.Uint(25), 70 titleTag: types.String("Dufus"), 71 greatTag: types.Bool(false), 72 })), 73 } 74 75 func TestInMemTable(t *testing.T) { 76 imt := NewInMemTable(rowSch) 77 78 func() { 79 var wr TableWriteCloser 80 wr = NewInMemTableWriter(imt) 81 defer wr.Close(context.Background()) 82 83 for _, row := range rows { 84 err := wr.WriteRow(context.Background(), row) 85 86 if err != nil { 87 t.Fatal("Failed to write row") 88 } 89 } 90 }() 91 92 func() { 93 var r TableReadCloser 94 r = NewInMemTableReader(imt) 95 defer r.Close(context.Background()) 96 97 for _, expectedRow := range rows { 98 actualRow, err := r.ReadRow(context.Background()) 99 100 if err != nil { 101 t.Error("Unexpected read error") 102 } else if !row.AreEqual(expectedRow, actualRow, rowSch) { 103 t.Error("Unexpected row value") 104 } 105 } 106 107 _, err := r.ReadRow(context.Background()) 108 109 if err != io.EOF { 110 t.Error("Should have reached the end.") 111 } 112 }() 113 } 114 115 func TestPipeRows(t *testing.T) { 116 imt := NewInMemTableWithData(rowSch, rows) 117 imtt2 := NewInMemTable(rowSch) 118 119 var err error 120 func() { 121 rd := NewInMemTableReader(imt) 122 defer rd.Close(context.Background()) 123 wr := NewInMemTableWriter(imtt2) 124 defer wr.Close(context.Background()) 125 _, _, err = PipeRows(context.Background(), rd, wr, false) 126 }() 127 128 if err != nil { 129 t.Error("Error piping rows from reader to writer", err) 130 } 131 132 if imt.NumRows() != imtt2.NumRows() { 133 t.Error("Row counts should match") 134 } 135 136 for i := 0; i < imt.NumRows(); i++ { 137 r1, err1 := imt.GetRow(i) 138 r2, err2 := imtt2.GetRow(i) 139 140 if err1 != nil || err2 != nil { 141 t.Fatal("Couldn't Get row.") 142 } 143 144 if !row.AreEqual(r1, r2, rowSch) { 145 t.Error("Rows should be the same.", row.Fmt(context.Background(), r1, rowSch), "!=", row.Fmt(context.Background(), r2, rowSch)) 146 } 147 } 148 } 149 150 func TestReadAllRows(t *testing.T) { 151 imt := NewInMemTableWithData(rowSch, rows) 152 153 var err error 154 var numBad int 155 var results []row.Row 156 func() { 157 rd := NewInMemTableReader(imt) 158 defer rd.Close(context.Background()) 159 results, numBad, err = ReadAllRows(context.Background(), rd, true) 160 }() 161 162 if err != nil { 163 t.Fatal("Error reading rows") 164 } 165 166 if len(rows) != len(results) { 167 t.Error("Unexpected count.") 168 } 169 170 if numBad != 0 { 171 t.Error("Unexpected BadRow Count") 172 } 173 174 for i := 0; i < len(rows); i++ { 175 if !row.AreEqual(rows[i], results[i], rowSch) { 176 t.Error(row.Fmt(context.Background(), rows[i], rowSch), "!=", row.Fmt(context.Background(), results[i], rowSch)) 177 } 178 } 179 } 180 181 /* 182 func TestReadAllRowsToMap(t *testing.T) { 183 imt := NewInMemTableWithData(rowSch, rows) 184 greatIndex := rowSch.GetFieldIndex("is_great") 185 186 var err error 187 var numBad int 188 var results map[types.Value][]row.Row 189 func() { 190 rd := NewInMemTableReader(imt) 191 defer rd.Close() 192 results, numBad, err = ReadAllRowsToMap(rd, greatIndex, true) 193 }() 194 195 if err != nil { 196 t.Fatal("Error reading rows") 197 } 198 199 if numBad != 0 { 200 t.Error("Unexpected BadRow Count") 201 } 202 203 if len(results) != 2 { 204 t.Error("Unexpected count.") 205 } 206 207 if len(results[types.Bool(true)]) != 2 || len(results[types.Bool(false)]) != 1 { 208 t.Error("Unexpected count for one or more values of is_great") 209 } 210 211 for _, great := range []types.Bool{types.Bool(true), types.Bool(false)} { 212 for i, j := 0, 0; i < len(rows); i++ { 213 rowIsGreat, _ := rows[i].CurrData().GetField(greatIndex) 214 215 if rowIsGreat == great { 216 if !RowsEqualIgnoringSchema(rows[i], results[great][j]) { 217 t.Error(RowFmt(rows[i]), "!=", RowFmt(results[great][j])) 218 } 219 j++ 220 } 221 } 222 } 223 } 224 */