src/StreamRelationalReader.h
branchv_0
changeset 18 e11f1ad20826
parent 17 ec750c536705
child 19 3e1308e7606d
equal deleted inserted replaced
17:ec750c536705 18:e11f1ad20826
    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