src/RecfileCommand.h
branchv_0
changeset 4 b5239b4b345b
parent 3 891fe13d7397
child 8 9c8c20c3bd64
equal deleted inserted replaced
3:891fe13d7397 4:b5239b4b345b
    46 
    46 
    47 	class RecfileHandler {
    47 	class RecfileHandler {
    48 	private:
    48 	private:
    49 		RelationalWriter* writer;
    49 		RelationalWriter* writer;
    50 		string_t currentRelationName;
    50 		string_t currentRelationName;
       
    51 		std::vector<AttributeMetadata> currentAttributeMetadata;
    51 		std::vector<string_t> currentRecord;
    52 		std::vector<string_t> currentRecord;
    52 		std::vector<std::vector<string_t>> currentRecords;
    53 		std::vector<std::vector<string_t>> currentRecords;
    53 		size_t prefetchCount = 1;
    54 		size_t prefetchCount = 1;
    54 		bool headerWritten = false;
    55 		bool headerWritten = false;
    55 
    56 
    56 		void writeHeader() {
    57 		void writeHeader() {
    57 			if (headerWritten) return;
    58 			if (headerWritten) return;
    58 
    59 
    59 			std::vector<AttributeMetadata> attributeMetadata;
    60 			if (currentRelationName.size() == 0) currentRelationName = L"recfile";
    60 
    61 
    61 			// TODO: writer->startRelation(currentRelationName, attributeMetadata, true);
    62 			std::set<string_t> uniqueAttributeNames;
    62 
    63 
    63 			headerWritten = true;
    64 			// TODO: add also attribute names from type hints from recfile metadata
    64 		}
       
    65 
       
    66 		void writeRecords() {
       
    67 			for (int i = 0; i < currentRecords.size(); i++) {
    65 			for (int i = 0; i < currentRecords.size(); i++) {
    68 				std::vector<string_t> record = currentRecords[i];
    66 				std::vector<string_t> record = currentRecords[i];
    69 				std::wcerr << L"record: " << std::endl;
       
    70 				for (int j = 0; j < record.size(); j += 2) {
    67 				for (int j = 0; j < record.size(); j += 2) {
    71 					std::wcerr << L"  '" << record[j] << L"': '" << record[j + 1] << L"'" << std::endl;
    68 					if (uniqueAttributeNames.insert(record[j]).second) {
    72 					// TODO: writer->writeAttribute()
    69 						currentAttributeMetadata.push_back({record[j], TypeId::STRING}); // TODO: type from type hints
       
    70 					}
    73 				}
    71 				}
    74 			}
    72 			}
       
    73 
       
    74 			writer->startRelation(currentRelationName, currentAttributeMetadata, true);
       
    75 			headerWritten = true;
       
    76 		}
       
    77 
       
    78 		string_t findValue(std::vector<string_t>& record, TypeId type, string_t& name) {
       
    79 			for (int j = 0; j < record.size(); j += 2) if (record[j] == name) return record[j + 1];
       
    80 			return L""; // TODO: proper empty/null value for given type
       
    81 		}
       
    82 
       
    83 		void writeRecords() {
       
    84 			for (std::vector<string_t> record : currentRecords) {
       
    85 				for (AttributeMetadata a : currentAttributeMetadata) {
       
    86 					writer->writeAttribute(findValue(record, a.typeId, a.attributeName));
       
    87 				}
       
    88 			}
    75 			currentRecords.clear();
    89 			currentRecords.clear();
    76 		}
    90 		}
    77 
    91 
    78 		void metadata(const string_t& name, const string_t& value) {
    92 		void metadata(const string_t& name, const string_t& value) {
    79 			std::wcerr << L"metadata(" << name << L", " << value << L");" << std::endl; // TODO: remove debug
       
    80 
       
    81 			if (name == L"rec") {
    93 			if (name == L"rec") {
    82 				currentRelationName = value;
    94 				currentRelationName = value;
       
    95 				currentAttributeMetadata.clear();
    83 				currentRecord.clear();
    96 				currentRecord.clear();
    84 				currentRecords.clear();
    97 				currentRecords.clear();
    85 				headerWritten = false;
    98 				headerWritten = false;
    86 			} else if (name == L"type") {
    99 			} else if (name == L"type") {
    87 				// TODO: save type hint
   100 				// TODO: save type hint
    89 				// ignore – other recfile metadata like keys or auto-increments
   102 				// ignore – other recfile metadata like keys or auto-increments
    90 			}
   103 			}
    91 		}
   104 		}
    92 
   105 
    93 		void data(const string_t& name, const string_t& value) {
   106 		void data(const string_t& name, const string_t& value) {
    94 			std::wcerr << L"data(" << name << L", " << value << L");" << std::endl; // TODO: remove debug
       
    95 			currentRecord.push_back(name);
   107 			currentRecord.push_back(name);
    96 			currentRecord.push_back(value);
   108 			currentRecord.push_back(value);
    97 		}
   109 		}
    98 
   110 
    99 		void comment(const string_t& value) {
   111 		void comment(const string_t& value) {
   100 			// ignore comments
   112 			// ignore comments
   101 		}
   113 		}
   102 
   114 
   103 		void separator() {
   115 		void separator() {
   104 			std::wcerr << L"separator()" << std::endl; // TODO: remove debug
       
   105 			if (currentRecord.size()) {
   116 			if (currentRecord.size()) {
   106 				currentRecords.push_back(currentRecord);
   117 				currentRecords.push_back(currentRecord);
   107 				currentRecord.clear();
   118 				currentRecord.clear();
   108 			}
   119 			}
   109 
   120 
   112 				writeRecords();
   123 				writeRecords();
   113 			}
   124 			}
   114 		}
   125 		}
   115 
   126 
   116 		void end() {
   127 		void end() {
   117 			std::wcerr << L"end();" << std::endl; // TODO: remove debug
       
   118 			if (currentRecord.size()) currentRecords.push_back(currentRecord);
   128 			if (currentRecord.size()) currentRecords.push_back(currentRecord);
   119 			writeHeader();
   129 			writeHeader();
   120 			writeRecords();
   130 			writeRecords();
   121 		}
   131 		}
   122 
   132 
   233 						break;
   243 						break;
   234 					default:
   244 					default:
   235 						throw RelpipeWriterException(L"Unknown ParserState: " + std::to_wstring((int) state) + L" in RecfileParser."); // TODO: better exception
   245 						throw RelpipeWriterException(L"Unknown ParserState: " + std::to_wstring((int) state) + L" in RecfileParser."); // TODO: better exception
   236 				}
   246 				}
   237 			}
   247 			}
   238 			emitLogicalLine(type, name, value);
   248 			if (name.tellp()) emitLogicalLine(type, name, value);
   239 			handler.logicalLine(RecfileLineType::END);
   249 			handler.logicalLine(RecfileLineType::END);
   240 		}
   250 		}
   241 	};
   251 	};
   242 
   252 
   243 public:
   253 public: