first working version v_0 v0.11
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sun, 07 Apr 2019 02:21:57 +0200
branchv_0
changeset 4 b5239b4b345b
parent 3 891fe13d7397
child 5 12b69d6b2875
first working version
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<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);
 		}
 	};