--- 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<AttributeMetadata> currentAttributeMetadata;
std::vector<string_t> currentRecord;
std::vector<std::vector<string_t>> currentRecords;
size_t prefetchCount = 1;
@@ -56,30 +57,42 @@
void writeHeader() {
if (headerWritten) return;
- std::vector<AttributeMetadata> attributeMetadata;
+ if (currentRelationName.size() == 0) currentRelationName = L"recfile";
+
+ std::set<string_t> 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<string_t> 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<string_t>& 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<string_t> 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<string_t> 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);
}
};