# HG changeset patch # User František Kučera # Date 1546984161 -3600 # Node ID 82f86dc4833957a0e2c4472627967def07d5ae13 # Parent 97967db4b95b0ec61188e2c7c1d2f5b104d9a7ed first working version 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() { diff -r 97967db4b95b -r 82f86dc48339 src/RelpipeCSVWriterException.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/RelpipeCSVWriterException.h Tue Jan 08 22:49:21 2019 +0100 @@ -0,0 +1,44 @@ +/** + * Relational pipes + * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include + +using namespace std; + +namespace relpipe { +namespace out { +namespace csv { + +class RelpipeCSVWriterException { +private: + wstring message; +public: + + RelpipeCSVWriterException(wstring message) : message(message) { + } + + wstring getMessge() { + return message; + } + +}; + +} +} +} \ No newline at end of file diff -r 97967db4b95b -r 82f86dc48339 src/relpipe-out-csv.cpp --- a/src/relpipe-out-csv.cpp Tue Jan 08 18:40:15 2019 +0100 +++ b/src/relpipe-out-csv.cpp Tue Jan 08 22:49:21 2019 +0100 @@ -27,6 +27,7 @@ #include #include "CSVHandler.h" +#include "RelpipeCSVWriterException.h" using namespace relpipe::cli; using namespace relpipe::reader; @@ -53,6 +54,9 @@ fwprintf(stderr, L"Caught Reader exception: %ls\n", e.getMessge().c_str()); fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); resultCode = CLI::EXIT_CODE_DATA_ERROR; + } catch (RelpipeCSVWriterException e) { + fwprintf(stderr, L"Error while generating CSV: %ls\n", e.getMessge().c_str()); + resultCode = CLI::EXIT_CODE_DATA_ERROR; } return resultCode;