# HG changeset patch # User František Kučera # Date 1554596517 -7200 # Node ID b5239b4b345b792d11c0953d9c009e93d85c7ef5 # Parent 891fe13d73979a6d69dfac0949bcd07933d1b207 first working version diff -r 891fe13d7397 -r b5239b4b345b src/RecfileCommand.h --- a/src/RecfileCommand.h Sun Apr 07 01:10:31 2019 +0200 +++ b/src/RecfileCommand.h Sun Apr 07 02:21:57 2019 +0200 @@ -48,6 +48,7 @@ private: RelationalWriter* writer; string_t currentRelationName; + std::vector currentAttributeMetadata; std::vector currentRecord; std::vector> currentRecords; size_t prefetchCount = 1; @@ -56,30 +57,42 @@ void writeHeader() { if (headerWritten) return; - std::vector attributeMetadata; + if (currentRelationName.size() == 0) currentRelationName = L"recfile"; + + std::set uniqueAttributeNames; - // TODO: writer->startRelation(currentRelationName, attributeMetadata, true); + // TODO: add also attribute names from type hints from recfile metadata + for (int i = 0; i < currentRecords.size(); i++) { + std::vector record = currentRecords[i]; + for (int j = 0; j < record.size(); j += 2) { + if (uniqueAttributeNames.insert(record[j]).second) { + currentAttributeMetadata.push_back({record[j], TypeId::STRING}); // TODO: type from type hints + } + } + } + writer->startRelation(currentRelationName, currentAttributeMetadata, true); headerWritten = true; } + string_t findValue(std::vector& record, TypeId type, string_t& name) { + for (int j = 0; j < record.size(); j += 2) if (record[j] == name) return record[j + 1]; + return L""; // TODO: proper empty/null value for given type + } + void writeRecords() { - for (int i = 0; i < currentRecords.size(); i++) { - std::vector record = currentRecords[i]; - std::wcerr << L"record: " << std::endl; - for (int j = 0; j < record.size(); j += 2) { - std::wcerr << L" '" << record[j] << L"': '" << record[j + 1] << L"'" << std::endl; - // TODO: writer->writeAttribute() + for (std::vector record : currentRecords) { + for (AttributeMetadata a : currentAttributeMetadata) { + writer->writeAttribute(findValue(record, a.typeId, a.attributeName)); } } currentRecords.clear(); } void metadata(const string_t& name, const string_t& value) { - std::wcerr << L"metadata(" << name << L", " << value << L");" << std::endl; // TODO: remove debug - if (name == L"rec") { currentRelationName = value; + currentAttributeMetadata.clear(); currentRecord.clear(); currentRecords.clear(); headerWritten = false; @@ -91,7 +104,6 @@ } void data(const string_t& name, const string_t& value) { - std::wcerr << L"data(" << name << L", " << value << L");" << std::endl; // TODO: remove debug currentRecord.push_back(name); currentRecord.push_back(value); } @@ -101,7 +113,6 @@ } void separator() { - std::wcerr << L"separator()" << std::endl; // TODO: remove debug if (currentRecord.size()) { currentRecords.push_back(currentRecord); currentRecord.clear(); @@ -114,7 +125,6 @@ } void end() { - std::wcerr << L"end();" << std::endl; // TODO: remove debug if (currentRecord.size()) currentRecords.push_back(currentRecord); writeHeader(); writeRecords(); @@ -235,7 +245,7 @@ throw RelpipeWriterException(L"Unknown ParserState: " + std::to_wstring((int) state) + L" in RecfileParser."); // TODO: better exception } } - emitLogicalLine(type, name, value); + if (name.tellp()) emitLogicalLine(type, name, value); handler.logicalLine(RecfileLineType::END); } };