support signed integers, negative numbers; binary format change: encode numbers as SLEB128 v_0 v0.15
authorFrantišek Kučera <franta-hg@frantovo.cz>
Fri, 13 Dec 2019 22:19:39 +0100
branchv_0
changeset 10 c59363fd805b
parent 9 c28c6eda540f
child 11 b73d5d8d46f1
support signed integers, negative numbers; binary format change: encode numbers as SLEB128
src/RecfileCommand.h
--- a/src/RecfileCommand.h	Wed Oct 30 16:47:42 2019 +0100
+++ b/src/RecfileCommand.h	Fri Dec 13 22:19:39 2019 +0100
@@ -21,6 +21,7 @@
 #include <sstream>
 #include <vector>
 #include <set>
+#include <regex>
 
 #include <relpipe/writer/typedefs.h>
 #include <relpipe/writer/RelationalWriter.h>
@@ -48,11 +49,24 @@
 		RelationalWriter* writer;
 		string_t currentRelationName;
 		std::vector<AttributeMetadata> currentAttributeMetadata;
+		std::vector<AttributeMetadata> currentTypeHints;
 		std::vector<string_t> currentRecord;
 		std::vector<std::vector<string_t>> currentRecords;
 		size_t prefetchCount = 1;
 		bool headerWritten = false;
 
+		TypeId findType(string_t attributeName, TypeId defaultType = TypeId::STRING) {
+			for (AttributeMetadata m : currentTypeHints) if (m.attributeName == attributeName) return m.typeId;
+			return defaultType;
+		}
+
+		TypeId recType2typeId(string_t recType) {
+			// TODO: support more types
+			// boolean is currently unsupported, because NULLs are not implemented yet and recfile booleans might be null
+			if (recType == L"int") return TypeId::INTEGER;
+			else return TypeId::STRING;
+		}
+
 		void writeHeader() {
 			if (headerWritten) return;
 
@@ -65,7 +79,7 @@
 				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
+						currentAttributeMetadata.push_back({record[j], findType(record[j])});
 					}
 				}
 			}
@@ -92,11 +106,13 @@
 			if (name == L"rec") {
 				currentRelationName = value;
 				currentAttributeMetadata.clear();
+				currentTypeHints.clear();
 				currentRecord.clear();
 				currentRecords.clear();
 				headerWritten = false;
 			} else if (name == L"type") {
-				// TODO: save type hint
+				std::wsmatch match;
+				if (regex_search(value, match, std::wregex(L"\\s?(.*)\\s+(.*)\\s?"))) currentTypeHints.push_back({match[1], recType2typeId(match[2])});
 			} else {
 				// ignore – other recfile metadata like keys or auto-increments
 			}