nextRow attempts to read the next row from the data and return it, and returns true if a row was read
(ctx *sql.Context, reader *csvReader)
| 70 | |
| 71 | // nextRow attempts to read the next row from the data and return it, and returns true if a row was read |
| 72 | func (cdl *CsvDataLoader) nextRow(ctx *sql.Context, reader *csvReader) (sql.Row, bool, error) { |
| 73 | if cdl.removeHeader { |
| 74 | _, err := reader.readLine() |
| 75 | cdl.removeHeader = false |
| 76 | if err != nil { |
| 77 | return nil, false, err |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | record, err := reader.ReadSqlRow() |
| 82 | if err != nil { |
| 83 | if ple, ok := err.(*partialLineError); ok { |
| 84 | cdl.partialRecord = ple.partialLine |
| 85 | return nil, false, nil |
| 86 | } |
| 87 | |
| 88 | // csvReader will return a BadRow error if it encounters an input line without the |
| 89 | // correct number of columns. If we see the end of data marker, then break out of the |
| 90 | // loop and return from this function without returning an error. |
| 91 | if _, ok := err.(*table.BadRow); ok { |
| 92 | if len(record) == 1 && record[0] == "\\." { |
| 93 | return nil, false, nil |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | if err != io.EOF { |
| 98 | return nil, false, err |
| 99 | } |
| 100 | |
| 101 | recordValues := make([]string, 0, len(record)) |
| 102 | for _, v := range record { |
| 103 | recordValues = append(recordValues, fmt.Sprintf("%v", v)) |
| 104 | } |
| 105 | cdl.partialRecord = strings.Join(recordValues, ",") |
| 106 | return nil, false, nil |
| 107 | } |
| 108 | |
| 109 | // If we see the end of data marker, then break out of the loop. Normally this will happen in the code |
| 110 | // above when we receive a BadRow error, since there won't be enough values, but if a table only has |
| 111 | // one column, we won't get a BadRow error, and we'll handle the end of data marker here. |
| 112 | if len(record) == 1 && record[0] == "\\." { |
| 113 | return nil, false, nil |
| 114 | } |
| 115 | |
| 116 | if len(record) > len(cdl.colTypes) { |
| 117 | return nil, false, errors.Errorf("extra data after last expected column") |
| 118 | } else if len(record) < len(cdl.colTypes) { |
| 119 | return nil, false, errors.Errorf(`missing data for column "%s"`, cdl.sch[len(record)].Name) |
| 120 | } |
| 121 | |
| 122 | // Cast the values using I/O input |
| 123 | row := make(sql.Row, len(cdl.colTypes)) |
| 124 | for i := range cdl.colTypes { |
| 125 | if record[i] == nil { |
| 126 | row[i] = nil |
| 127 | } else { |
| 128 | row[i], err = cdl.colTypes[i].IoInput(ctx, fmt.Sprintf("%v", record[i])) |
| 129 | if err != nil { |
no test coverage detected