--- 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<std::codecvt_utf8<wchar_t>> convertor; // we generate YAML always in UTF-8 like XML?
std::vector<relpipe::reader::handlers::AttributeMetadata> 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<relpipe::reader::handlers::AttributeMetadata> 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++;
}