27 std::istream &input; |
27 std::istream &input; |
28 types::BooleanDataTypeReader booleanReader; |
28 types::BooleanDataTypeReader booleanReader; |
29 types::IntegerDataTypeReader integerReader; |
29 types::IntegerDataTypeReader integerReader; |
30 types::StringDataTypeReader stringReader; |
30 types::StringDataTypeReader stringReader; |
31 std::vector<DataTypeReaderBase*> readers = {&booleanReader, &integerReader, &stringReader}; |
31 std::vector<DataTypeReaderBase*> readers = {&booleanReader, &integerReader, &stringReader}; |
|
32 |
32 std::vector<handlers::RelationalReaderStringHadler*> stringHandlers; |
33 std::vector<handlers::RelationalReaderStringHadler*> stringHandlers; |
33 std::vector<handlers::RelationalReaderValueHadler*> valueHandlers; |
34 std::vector<handlers::RelationalReaderValueHadler*> valueHandlers; |
34 |
35 |
35 /** |
36 /** |
36 * count of columns in the current table |
37 * count of columns in the current table |
43 |
44 |
44 /** |
45 /** |
45 * types of columns in the current table |
46 * types of columns in the current table |
46 */ |
47 */ |
47 std::vector<TypeId> columnTypes; |
48 std::vector<TypeId> columnTypes; |
|
49 std::vector<string_t> columnNames; |
|
50 std::vector<std::pair<string_t, TypeId>> columns; |
|
51 |
|
52 /** |
|
53 * TODO: remove? |
|
54 */ |
|
55 string_t readString(std::istream &input, const TypeId typeId) { |
|
56 for (DataTypeReaderBase* reader : readers) if (reader->supports(typeId)) return reader->readString(input); |
|
57 throw RelpipeReaderException(L"Unsupported data type: " + (int) typeId); |
|
58 } |
|
59 |
|
60 void read(std::istream &input, std::function<void(const void *, const std::type_info&) > handler, const TypeId typeId) { |
|
61 for (DataTypeReaderBase* reader : readers) if (reader->supports(typeId)) return reader->read(input, handler); |
|
62 throw RelpipeReaderException(L"Unsupported data type: " + (int) typeId); |
|
63 } |
|
64 |
|
65 void read(std::istream &input, std::function<void(const string_t&, const void *, const std::type_info&) > handler, const TypeId typeId) { |
|
66 for (DataTypeReaderBase* reader : readers) if (reader->supports(typeId)) return reader->read(input, handler); |
|
67 throw RelpipeReaderException(L"Unsupported data type: " + (int) typeId); |
|
68 } |
48 |
69 |
49 public: |
70 public: |
50 |
71 |
51 StreamRelationalReader(std::istream &input) : |
72 StreamRelationalReader(std::istream &input) : |
52 input(input) { |
73 input(input) { |
64 void addHandler(handlers::RelationalReaderValueHadler* handler) override { |
85 void addHandler(handlers::RelationalReaderValueHadler* handler) override { |
65 valueHandlers.push_back(handler); |
86 valueHandlers.push_back(handler); |
66 } |
87 } |
67 |
88 |
68 void process() override { |
89 void process() override { |
69 for (int i = 0; i < stringHandlers.size(); i++) { |
90 |
70 // FIXME: parse and call methods |
91 while (true) { |
71 stringHandlers[i]->startRelation(L"TODO: table",{ |
92 integer_t dataPart; |
72 {L"a", TypeId::STRING}, |
93 try { |
73 {L"b", TypeId::STRING}, |
94 dataPart = integerReader.readValue(input); |
74 {L"c", TypeId::STRING} |
95 // output << "dataPart: " << dataPart << endl; |
75 }); |
96 } catch (RelpipeReaderException e) { |
|
97 if (input.eof() && input.gcount() == 0) { |
|
98 if (dataPart == DATA_PART_ROW) { |
|
99 // last part was row |
|
100 // input was fully read |
|
101 // we are finished |
|
102 // TODO: printCachedData(output); ??? |
|
103 return; |
|
104 } else if (dataPart == DATA_PART_START) { |
|
105 // Empty relation might be weird but it is valid data. |
|
106 // Actually, it is not so weird as it looks. |
|
107 // fwprintf(stderr, L"Warning: The table has no rows. Weird… but OK.\n"); |
|
108 return; |
|
109 } else { |
|
110 // in current format, there is no other data part |
|
111 // so this will never happen |
|
112 // but maybe later… |
|
113 throw RelpipeReaderException(L"Unexpected EOF"); |
|
114 } |
|
115 } else if (input.eof()) { |
|
116 fwprintf(stderr, L"Error: found some unexpected data on the input stream: %d\n", input.gcount()); |
|
117 throw e; |
|
118 } else { |
|
119 // other error |
|
120 throw e; |
|
121 } |
|
122 } |
|
123 |
|
124 if (dataPart == DATA_PART_START) { |
|
125 // Print data of previous table |
|
126 // TODO: if (values.size() > 0) printCachedData(output); ??? |
|
127 |
|
128 // Read table name |
|
129 string_t tableName = stringReader.readValue(input); |
|
130 |
|
131 // Read column count |
|
132 columnCount = integerReader.readValue(input); |
|
133 |
|
134 columnTypes.resize(columnCount); |
|
135 columnNames.resize(columnCount); |
|
136 columns.resize(columnCount); |
|
137 |
|
138 // Read column names |
|
139 for (int i = 0; i < columnCount; i++) { |
|
140 columnNames[i] = stringReader.readValue(input); |
|
141 } |
|
142 |
|
143 // Read column types |
|
144 for (int i = 0; i < columnCount; i++) { |
|
145 TypeId typeId = (TypeId) integerReader.readValue(input); // TODO: přetypování OK? |
|
146 string_t typeCode = toTypeCode(typeId); // validate typeId TODO: je potřeba? |
|
147 columnTypes[i] = typeId; |
|
148 } |
|
149 |
|
150 for (int i = 0; i < columnCount; i++) { |
|
151 columns[i] = {columnNames[i], columnTypes[i]}; |
|
152 } |
|
153 |
|
154 for (int i = 0; i < stringHandlers.size(); i++) stringHandlers[i]->startRelation(tableName, columns); |
|
155 for (int i = 0; i < valueHandlers.size(); i++) valueHandlers[i]->startRelation(tableName, columns); |
|
156 |
|
157 } else if (dataPart == DATA_PART_ROW) { |
|
158 for (int i = 0; i < columnCount; i++) { |
|
159 TypeId typeId = columnTypes[i]; |
|
160 |
|
161 if (stringHandlers.empty()) { |
|
162 read(input, [&](const void * rawValue, const std::type_info & typeInfo) { |
|
163 for (int i = 0; i < valueHandlers.size(); i++) valueHandlers[i]->attribute(rawValue, typeInfo); |
|
164 }, typeId); |
|
165 } else { |
|
166 read(input, [&](const string_t& stringValue, const void * rawValue, const std::type_info & typeInfo) { |
|
167 for (int i = 0; i < stringHandlers.size(); i++) stringHandlers[i]->attribute(stringValue); |
|
168 for (int i = 0; i < valueHandlers.size(); i++) valueHandlers[i]->attribute(rawValue, typeInfo); |
|
169 }, typeId); |
|
170 } |
|
171 } |
|
172 |
|
173 } else { |
|
174 throw RelpipeReaderException(L"Unknown data part"); |
|
175 } |
76 } |
176 } |
77 |
177 |
78 for (int i = 0; i < valueHandlers.size(); i++) { |
178 throw RelpipeReaderException(L"Unexpected exception"); // should never happen |
79 // FIXME: parse and call methods |
|
80 valueHandlers[i]->startRelation(L"TODO: table value",{ |
|
81 {L"av", TypeId::STRING}, |
|
82 {L"bv", TypeId::STRING}, |
|
83 {L"cv", TypeId::STRING} |
|
84 }); |
|
85 } |
|
86 |
|
87 // FIXME: parse and call methods |
|
88 for (int row = 0; row < 3; row++) { |
|
89 for (int i = 0; i < stringHandlers.size(); i++) stringHandlers[i]->attribute(L"x"); |
|
90 |
|
91 } |
|
92 |
179 |
93 } |
180 } |
94 |
181 |
95 }; |
182 }; |
96 |
183 |