diff -r 157bb1d5e08a -r 15ee963675af src/CSVCommand.cpp --- a/src/CSVCommand.cpp Wed Sep 23 11:26:33 2020 +0200 +++ b/src/CSVCommand.cpp Wed Sep 23 16:58:48 2020 +0200 @@ -87,7 +87,7 @@ return false; } -void CSVCommand::process(std::istream& input, const vector& args, std::shared_ptr writer) { +void CSVCommand::process(std::istream& input, std::shared_ptr writer, Configuration& configuration) { wstring_convert < codecvt_utf8> convertor; // UTF-8 is required for CSV vector metadata; bool headerDone = false; @@ -105,30 +105,28 @@ metadata.push_back(am); if (lastInRecord) { - /* - * Usage (simple syntax): - * relpipe-in-csv → default relation name, attribute names on the first line, all types are string - * relpipe-in-csv my_relation → custom relation name - * relpipe-in-csv my_relation a b c → custom relation name, custom attribute names (a,b,c), first line contains data - * relpipe-in-csv my_relation a integer b string c boolean → custom relation name, custom attribute names (a,b,c), custom types (integer,string,boolean), first line contains data - */ + // TODO: allow types on CLI and names from CSV? + // TODO: allow types on the second line of the CSV? + // TODO: allow regex pattern+replacement for extracting name and type from the first line of the CSV? + // TODO: allow attribute filtering, subset, like relpipe-tr-cur? + // TODO: allow skipping lines, like tail -n +2 ? + + vector firstLine; - vector firstLine; - if (args.size() == (1 + metadata.size())) { + if (metadata.size() == configuration.attributes.size()) { for (int i = 0; i < metadata.size(); i++) { firstLine.push_back(metadata[i].attributeName); - metadata[i].attributeName = args[1 + i]; + metadata[i].attributeName = configuration.attributes[i].name; + metadata[i].typeId = configuration.attributes[i].type; } - } else if (args.size() == (1 + 2 * metadata.size())) { - for (int i = 0; i < metadata.size(); i++) { - firstLine.push_back(metadata[i].attributeName); - metadata[i].attributeName = args[1 + i * 2]; - metadata[i].typeId = writer->toTypeId(args[1 + i * 2 + 1]); - } + } else if (configuration.attributes.size() == 0) { + // first line contains attribute names and type is always string + } else { + throw RelpipeWriterException(L"Declared attribute count (" + std::to_wstring(configuration.attributes.size()) + L") does not match with number of columns of the first line (" + std::to_wstring(metadata.size()) + L")"); } headerDone = true; - writer->startRelation(args.size() > 0 ? args[0] : L"csv", metadata, true); + writer->startRelation(configuration.relation, metadata, true); if (firstLine.size()) { for (string_t value : firstLine) writer->writeAttribute(value); }