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  */