Vince's CSV Parser
Loading...
Searching...
No Matches
csv_utility.cpp
1#include "csv_utility.hpp"
2#include "data_frame.hpp"
3
4namespace csv {
5#if CSV_EXCEPTIONS_ENABLED
6 std::unordered_map<std::string, DataType> csv_data_types(CSVReader& reader) {
7 CSVError error;
8 auto result = try_csv_data_types(reader, error);
9 internals::throw_dataframe_error(error);
10 return result;
11 }
12#endif
13
14 std::unordered_map<std::string, DataType> try_csv_data_types(CSVReader& reader, CSVError& error) {
15 error.clear();
16 std::unordered_map<std::string, DataType> csv_dtypes;
17 const auto col_names = reader.get_col_names();
18 std::vector<std::unordered_map<DataType, size_t>> type_counts(col_names.size());
19 constexpr size_t TYPE_CHUNK_SIZE = 5000;
20
21 // A task owns one column's count map and error slot. Collect errors only
22 // after the executor joins, rather than racing on the caller's error.
23 std::vector<CSVError> column_errors(col_names.size());
24 auto count_column = [&column_errors](DataFrame<>::column_type column,
25 std::unordered_map<DataType, size_t>& counts) {
26 CSVError& column_error = column_errors[column.index()];
27 for (size_t row_index = 0; row_index < column.size(); ++row_index) {
28 const auto value = column.try_get_sv(row_index, column_error);
29 if (column_error) return;
30 counts[internals::data_type(value)]++;
31 }
32 };
33 DataFrameExecutor executor;
34 if (!internals::try_for_each_csv_chunk(reader,
35 [&executor, &type_counts, &column_errors, &count_column](DataFrame<>& batch, CSVError& failure) {
36 if (!batch.try_column_parallel_apply(executor, type_counts, count_column, failure)) return false;
37 for (const auto& column_error : column_errors) {
38 if (column_error) {
39 failure = column_error;
40 return false;
41 }
42 }
43 return true;
44 }, error, TYPE_CHUNK_SIZE)) return {};
45
46 for (size_t i = 0; i < col_names.size(); i++) {
47 auto& col = type_counts[i];
48 auto& col_name = col_names[i];
49
50 if (col[DataType::CSV_STRING])
51 csv_dtypes[col_name] = DataType::CSV_STRING;
52 else if (col[DataType::CSV_INT64])
53 csv_dtypes[col_name] = DataType::CSV_INT64;
54 else if (col[DataType::CSV_INT32])
55 csv_dtypes[col_name] = DataType::CSV_INT32;
56 else if (col[DataType::CSV_INT16])
57 csv_dtypes[col_name] = DataType::CSV_INT16;
58 else if (col[DataType::CSV_INT8])
59 csv_dtypes[col_name] = DataType::CSV_INT8;
60 else if (col[DataType::CSV_BOOL])
61 csv_dtypes[col_name] = DataType::CSV_BOOL;
62 else if (col[DataType::CSV_TIMESTAMP])
63 csv_dtypes[col_name] = DataType::CSV_TIMESTAMP;
64 else if (col[DataType::CSV_NULL])
65 csv_dtypes[col_name] = DataType::CSV_NULL;
66 else
67 csv_dtypes[col_name] = DataType::CSV_DOUBLE;
68 }
69
70 return csv_dtypes;
71 }
72}
Main class for parsing CSVs from files and in-memory sources.
The all encompassing namespace.
@ CSV_TIMESTAMP
Timestamp value.
@ CSV_INT64
64-bit integer
@ CSV_DOUBLE
Floating point value.
@ CSV_BOOL
Boolean value.
@ CSV_NULL
Empty string.
@ CSV_INT16
16-bit integer
@ CSV_INT32
32-bit integer
@ CSV_INT8
8-bit integer
@ CSV_STRING
Non-scalar string.
std::unordered_map< std::string, DataType > try_csv_data_types(CSVReader &reader, CSVError &error)
Infer SQL-friendly column data types from an existing CSVReader.
A diagnostic whose text remains valid for the lifetime of the error.
Definition csv_error.hpp:94