go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/pkg/funcs/read_csv.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package funcs 9 10 import ( 11 "context" 12 "encoding/csv" 13 "fmt" 14 "io" 15 "os" 16 "time" 17 18 "go.charczuk.com/projects/nodes/pkg/incrutil" 19 "go.charczuk.com/projects/nodes/pkg/types" 20 ) 21 22 // ReadCSV reads a csv from a given file input and returns a table. 23 // 24 // The table values initially will be string. 25 func ReadCSV(ctx context.Context, filepath string, modTime time.Time) (output *types.Table, err error) { 26 f, err := os.Open(os.ExpandEnv(filepath)) 27 if err != nil { 28 return 29 } 30 defer f.Close() 31 32 output = new(types.Table) 33 34 csvr := csv.NewReader(f) 35 var record []string 36 for { 37 record, err = csvr.Read() 38 if err == io.EOF { 39 err = nil 40 break 41 } 42 if len(output.Columns) == 0 { 43 output.Columns = make([]types.TableColumn, len(record)) 44 for index, value := range record { 45 output.Columns[index] = types.TableColumn{ 46 ValueType: incrutil.ValueTypeString, 47 Name: value, 48 } 49 } 50 continue 51 } 52 if len(record) > len(output.Columns) { 53 err = fmt.Errorf("invalid csv row; more columns present than the header row") 54 return 55 } 56 for index, value := range record { 57 output.Columns[index].Values = append(output.Columns[index].Values, value) 58 } 59 } 60 return 61 }