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 |