diff -r 97967db4b95b -r 82f86dc48339 src/CSVHandler.h --- a/src/CSVHandler.h Tue Jan 08 18:40:15 2019 +0100 +++ b/src/CSVHandler.h Tue Jan 08 22:49:21 2019 +0100 @@ -30,6 +30,8 @@ #include #include +#include "RelpipeCSVWriterException.h" + namespace relpipe { namespace out { namespace csv { @@ -41,19 +43,43 @@ class CSVHandler : public RelationalReaderStringHadler { private: std::ostream& output; - std::wstring_convert> convertor; // TODO: support also other encodings. + const char QUOTE = '"'; + std::wstring_convert> convertor; // TODO: local system encoding or generate CSV always in UTF-8 like XML? + std::vector firstAttributes; + integer_t valueCount = 0; public: CSVHandler(std::ostream& output) : output(output) { } void startRelation(string_t name, std::vector attributes) override { - + if (firstAttributes.empty()) { + firstAttributes = attributes; + for (auto attr : attributes) attribute(attr.getAttributeName()); + } else { + // TODO: UNION ALL if data types and attribute count matches + throw RelpipeCSVWriterException(L"Only a single relation can be converted to the CSV format."); + } } void attribute(const string_t& value) override { - output << convertor.to_bytes(value).c_str(); - output.put(0); + valueCount++; + + if (value.size() > 0) { + output << QUOTE; + for (auto ch : convertor.to_bytes(value)) { + if (ch == QUOTE) output << QUOTE << QUOTE; + else output << ch; + } + output << QUOTE; + } + + if (valueCount % firstAttributes.size()) { + output << ","; + } else { + output << std::endl; + valueCount = 0; + } } void endOfPipe() {