github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/mvdata/data_loc_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 mvdata 16 17 import ( 18 "context" 19 "fmt" 20 "reflect" 21 "testing" 22 23 "github.com/stretchr/testify/assert" 24 "github.com/stretchr/testify/require" 25 26 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 27 "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils" 28 "github.com/dolthub/dolt/go/libraries/doltcore/row" 29 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 30 "github.com/dolthub/dolt/go/libraries/doltcore/table" 31 "github.com/dolthub/dolt/go/libraries/doltcore/table/typed/json" 32 "github.com/dolthub/dolt/go/libraries/doltcore/table/untyped/csv" 33 "github.com/dolthub/dolt/go/libraries/utils/filesys" 34 "github.com/dolthub/dolt/go/store/types" 35 ) 36 37 const ( 38 testTableName = "test_table" 39 testSchemaFileName = "schema.sql" 40 testSchema = ` 41 CREATE TABLE test_table ( 42 a VARCHAR(120) COMMENT 'tag:0', 43 b VARCHAR(120) COMMENT 'tag:1', 44 PRIMARY KEY(a) 45 );` 46 ) 47 48 var rowMap = []map[string]interface{}{ 49 {"a": []string{"a", "b", "c"}}, 50 {"b": []string{"1", "2", "3"}}, 51 } 52 53 func createRootAndFS() (*doltdb.DoltDB, *doltdb.RootValue, filesys.Filesys) { 54 55 testHomeDir := "/user/bheni" 56 workingDir := "/user/bheni/datasets/states" 57 initialDirs := []string{testHomeDir, workingDir} 58 fs := filesys.NewInMemFS(initialDirs, nil, workingDir) 59 fs.WriteFile(testSchemaFileName, []byte(testSchema)) 60 ddb, _ := doltdb.LoadDoltDB(context.Background(), types.Format_Default, doltdb.InMemDoltDB) 61 ddb.WriteEmptyRepo(context.Background(), "billy bob", "bigbillieb@fake.horse") 62 63 cs, _ := doltdb.NewCommitSpec("master") 64 commit, _ := ddb.Resolve(context.Background(), cs, nil) 65 root, err := commit.GetRootValue() 66 67 if err != nil { 68 panic(err) 69 } 70 71 return ddb, root, fs 72 } 73 74 func TestBasics(t *testing.T) { 75 tests := []struct { 76 dl DataLocation 77 expectedStr string 78 expectedIsFileType bool 79 }{ 80 {NewDataLocation("", ".csv"), "stream", false}, 81 {NewDataLocation(testTableName, ""), DoltDB.ReadableStr() + ":" + testTableName, false}, 82 {NewDataLocation("file.csv", ""), CsvFile.ReadableStr() + ":file.csv", true}, 83 {NewDataLocation("file.psv", ""), PsvFile.ReadableStr() + ":file.psv", true}, 84 {NewDataLocation("file.json", ""), JsonFile.ReadableStr() + ":file.json", true}, 85 //{NewDataLocation("file.nbf", ""), NbfFile, "file.nbf", true}, 86 } 87 88 for _, test := range tests { 89 t.Run(test.dl.String(), func(t *testing.T) { 90 assert.Equal(t, test.expectedStr, test.dl.String()) 91 92 _, isFileType := test.dl.(FileDataLocation) 93 assert.Equal(t, test.expectedIsFileType, isFileType) 94 }) 95 } 96 } 97 98 var fakeFields = schema.NewColCollection( 99 schema.NewColumn("a", 0, types.StringKind, true, schema.NotNullConstraint{}), 100 schema.NewColumn("b", 1, types.StringKind, false), 101 ) 102 103 func mustRow(r row.Row, err error) row.Row { 104 if err != nil { 105 panic(err) 106 } 107 108 return r 109 } 110 111 var fakeSchema schema.Schema 112 var imt *table.InMemTable 113 var imtRows []row.Row 114 115 func init() { 116 fakeSchema = schema.MustSchemaFromCols(fakeFields) 117 118 imtRows = []row.Row{ 119 mustRow(row.New(types.Format_Default, fakeSchema, row.TaggedValues{0: types.String("a"), 1: types.String("1")})), 120 mustRow(row.New(types.Format_Default, fakeSchema, row.TaggedValues{0: types.String("b"), 1: types.String("2")})), 121 mustRow(row.New(types.Format_Default, fakeSchema, row.TaggedValues{0: types.String("c"), 1: types.String("3")})), 122 } 123 124 imt = table.NewInMemTableWithData(fakeSchema, imtRows) 125 } 126 127 func TestExists(t *testing.T) { 128 testLocations := []DataLocation{ 129 NewDataLocation(testTableName, ""), 130 NewDataLocation("file.csv", ""), 131 NewDataLocation("file.psv", ""), 132 NewDataLocation("file.json", ""), 133 //NewDataLocation("file.nbf", ""), 134 } 135 136 _, root, fs := createRootAndFS() 137 138 for _, loc := range testLocations { 139 t.Run(loc.String(), func(t *testing.T) { 140 if exists, err := loc.Exists(context.Background(), root, fs); err != nil { 141 t.Error(err) 142 } else if exists { 143 t.Error("Shouldn't exist before creation") 144 } 145 146 if tableVal, isTable := loc.(TableDataLocation); isTable { 147 var err error 148 root, err = root.CreateEmptyTable(context.Background(), tableVal.Name, fakeSchema) 149 assert.NoError(t, err) 150 } else if fileVal, isFile := loc.(FileDataLocation); isFile { 151 err := fs.WriteFile(fileVal.Path, []byte("test")) 152 assert.NoError(t, err) 153 } 154 155 if exists, err := loc.Exists(context.Background(), root, fs); err != nil { 156 t.Error(err) 157 } else if !exists { 158 t.Error("Should already exist after creation") 159 } 160 }) 161 } 162 } 163 164 type testDataMoverOptions struct{} 165 166 func (t testDataMoverOptions) WritesToTable() bool { 167 return true 168 } 169 170 func (t testDataMoverOptions) SrcName() string { 171 return "" 172 } 173 174 func (t testDataMoverOptions) DestName() string { 175 return testTableName 176 } 177 178 func TestCreateRdWr(t *testing.T) { 179 tests := []struct { 180 dl DataLocation 181 expectedRdT reflect.Type 182 expectedWrT reflect.Type 183 }{ 184 {NewDataLocation("file.csv", ""), reflect.TypeOf((*csv.CSVReader)(nil)).Elem(), reflect.TypeOf((*csv.CSVWriter)(nil)).Elem()}, 185 {NewDataLocation("file.psv", ""), reflect.TypeOf((*csv.CSVReader)(nil)).Elem(), reflect.TypeOf((*csv.CSVWriter)(nil)).Elem()}, 186 {NewDataLocation("file.json", ""), reflect.TypeOf((*json.JSONReader)(nil)).Elem(), reflect.TypeOf((*json.JSONWriter)(nil)).Elem()}, 187 //{NewDataLocation("file.nbf", ""), reflect.TypeOf((*nbf.NBFReader)(nil)).Elem(), reflect.TypeOf((*nbf.NBFWriter)(nil)).Elem()}, 188 } 189 190 dEnv := dtestutils.CreateTestEnv() 191 root, err := dEnv.WorkingRoot(context.Background()) 192 require.NoError(t, err) 193 dEnv.FS.WriteFile(testSchemaFileName, []byte(testSchema)) 194 195 mvOpts := &testDataMoverOptions{} 196 197 for idx, test := range tests { 198 fmt.Println(idx) 199 200 loc := test.dl 201 202 wr, err := loc.NewCreatingWriter(context.Background(), mvOpts, dEnv, root, true, fakeSchema, nil, true) 203 204 if err != nil { 205 t.Fatal("Unexpected error creating writer.", err) 206 } 207 208 actualWrT := reflect.TypeOf(wr).Elem() 209 if actualWrT != test.expectedWrT { 210 t.Fatal("Unexpected writer type. Expected:", test.expectedWrT.Name(), "actual:", actualWrT.Name()) 211 } 212 213 inMemRd := table.NewInMemTableReader(imt) 214 _, numBad, pipeErr := table.PipeRows(context.Background(), inMemRd, wr, false) 215 wr.Close(context.Background()) 216 217 if numBad != 0 || pipeErr != nil { 218 t.Fatal("Failed to write data. bad:", numBad, err) 219 } 220 221 if wr, ok := wr.(DataMoverCloser); ok { 222 root, err = wr.Flush(context.Background()) 223 assert.NoError(t, err) 224 } 225 226 rd, _, err := loc.NewReader(context.Background(), root, dEnv.FS, JSONOptions{TableName: testTableName, SchFile: testSchemaFileName}) 227 228 if err != nil { 229 t.Fatal("Unexpected error creating writer", err) 230 } 231 232 actualRdT := reflect.TypeOf(rd).Elem() 233 if actualRdT != test.expectedRdT { 234 t.Error("Unexpected reader type. Expected:", test.expectedRdT.Name(), "actual:", actualRdT.Name()) 235 } 236 237 rd.Close(context.Background()) 238 } 239 }