# HG changeset patch # User František Kučera # Date 1608744175 -3600 # Node ID af15c47f77ae478101f51ec3f2f4b14d16faad48 # Parent c52ca92aa593d50aee76f250ae2e68fc32059c92 convert data and metadata diff -r c52ca92aa593 -r af15c47f77ae src/YAMLHandler.h --- a/src/YAMLHandler.h Wed Dec 23 17:15:34 2020 +0100 +++ b/src/YAMLHandler.h Wed Dec 23 18:22:55 2020 +0100 @@ -35,15 +35,31 @@ class YAMLHandler : public relpipe::reader::handlers::RelationalReaderStringHandler { private: + const char ESC = '\\'; + const char Q = '"'; std::ostream& output; std::wstring_convert> convertor; // we generate YAML always in UTF-8 like XML? std::vector currentAttributes; size_t currentAttributeIndex = 0; + bool firstRecord; - void writeYamlValue(const relpipe::common::type::StringX& value) { - // TODO: escaping - output << convertor.to_bytes(value); + std::string escape(const relpipe::common::type::StringX& value) { + std::stringstream result; + result.put(Q); + for (char ch : convertor.to_bytes(value)) { + if (ch == Q) result.put(ESC).put(ch); + else result.put(ch); + } + result.put(Q); + return result.str(); } + + std::string indent(int level) { + std::stringstream result; + for (int i = 0; i < level; i++) result << " "; + return result.str(); + } + public: YAMLHandler(std::ostream& output) : output(output) { @@ -51,16 +67,30 @@ void startRelation(relpipe::common::type::StringX name, std::vector attributes) override { currentAttributes = attributes; + currentAttributeIndex = 0; + output << escape(name); + output << ":" << std::endl; + output << indent(1) << R"("attribute-metadata":)" << std::endl; + for (auto am : attributes) output << indent(2) << R"(- "name": )" << escape(am.getAttributeName()) << std::endl << indent(2) << R"( "type": )" << escape(am.getTypeName()) << std::endl; + firstRecord = true; } void attribute(const relpipe::common::type::StringX& value) override { + if (firstRecord) { + output << indent(1) << R"("record":)" << std::endl; + firstRecord = false; + } + if (currentAttributeIndex % currentAttributes.size() == 0) { currentAttributeIndex = 0; - + output << indent(2) << "- "; } else { - + output << indent(2) << " "; } + output << escape(currentAttributes[currentAttributeIndex].getAttributeName()) << ": "; + output << escape(value) << std::endl; + currentAttributeIndex++; }