src/YAMLHandler.h
branchv_0
changeset 1 af15c47f77ae
parent 0 c52ca92aa593
child 2 6839c85a9621
equal deleted inserted replaced
0:c52ca92aa593 1:af15c47f77ae
    33 namespace out {
    33 namespace out {
    34 namespace yaml {
    34 namespace yaml {
    35 
    35 
    36 class YAMLHandler : public relpipe::reader::handlers::RelationalReaderStringHandler {
    36 class YAMLHandler : public relpipe::reader::handlers::RelationalReaderStringHandler {
    37 private:
    37 private:
       
    38 	const char ESC = '\\';
       
    39 	const char Q = '"';
    38 	std::ostream& output;
    40 	std::ostream& output;
    39 	std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor; // we generate YAML always in UTF-8 like XML?
    41 	std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor; // we generate YAML always in UTF-8 like XML?
    40 	std::vector<relpipe::reader::handlers::AttributeMetadata> currentAttributes;
    42 	std::vector<relpipe::reader::handlers::AttributeMetadata> currentAttributes;
    41 	size_t currentAttributeIndex = 0;
    43 	size_t currentAttributeIndex = 0;
       
    44 	bool firstRecord;
    42 
    45 
    43 	void writeYamlValue(const relpipe::common::type::StringX& value) {
    46 	std::string escape(const relpipe::common::type::StringX& value) {
    44 		// TODO: escaping
    47 		std::stringstream result;
    45 		output << convertor.to_bytes(value);
    48 		result.put(Q);
       
    49 		for (char ch : convertor.to_bytes(value)) {
       
    50 			if (ch == Q) result.put(ESC).put(ch);
       
    51 			else result.put(ch);
       
    52 		}
       
    53 		result.put(Q);
       
    54 		return result.str();
    46 	}
    55 	}
       
    56 
       
    57 	std::string indent(int level) {
       
    58 		std::stringstream result;
       
    59 		for (int i = 0; i < level; i++) result << "  ";
       
    60 		return result.str();
       
    61 	}
       
    62 
    47 public:
    63 public:
    48 
    64 
    49 	YAMLHandler(std::ostream& output) : output(output) {
    65 	YAMLHandler(std::ostream& output) : output(output) {
    50 	}
    66 	}
    51 
    67 
    52 	void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
    68 	void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
    53 		currentAttributes = attributes;
    69 		currentAttributes = attributes;
       
    70 		currentAttributeIndex = 0;
       
    71 		output << escape(name);
       
    72 		output << ":" << std::endl;
       
    73 		output << indent(1) << R"("attribute-metadata":)" << std::endl;
       
    74 		for (auto am : attributes) output << indent(2) << R"(- "name": )" << escape(am.getAttributeName()) << std::endl << indent(2) << R"(  "type": )" << escape(am.getTypeName()) << std::endl;
       
    75 		firstRecord = true;
    54 	}
    76 	}
    55 
    77 
    56 	void attribute(const relpipe::common::type::StringX& value) override {
    78 	void attribute(const relpipe::common::type::StringX& value) override {
       
    79 		if (firstRecord) {
       
    80 			output << indent(1) << R"("record":)" << std::endl;
       
    81 			firstRecord = false;
       
    82 		}
       
    83 
    57 		if (currentAttributeIndex % currentAttributes.size() == 0) {
    84 		if (currentAttributeIndex % currentAttributes.size() == 0) {
    58 			currentAttributeIndex = 0;
    85 			currentAttributeIndex = 0;
    59 			
    86 			output << indent(2) << "- ";
    60 		} else {
    87 		} else {
    61 			
    88 			output << indent(2) << "  ";
    62 		}
    89 		}
       
    90 
       
    91 		output << escape(currentAttributes[currentAttributeIndex].getAttributeName()) << ": ";
       
    92 		output << escape(value) << std::endl;
    63 
    93 
    64 		currentAttributeIndex++;
    94 		currentAttributeIndex++;
    65 	}
    95 	}
    66 
    96 
    67 	void endOfPipe() {
    97 	void endOfPipe() {