26 |
26 |
27 /** |
27 /** |
28 * count of columns in the current table |
28 * count of columns in the current table |
29 */ |
29 */ |
30 integer_t columnCount; |
30 integer_t columnCount; |
|
31 /** |
|
32 * number of column (0 = first) that will be written; after writing, the number is increased and prepared for next one |
|
33 */ |
|
34 integer_t currentColumn; |
31 |
35 |
32 /** |
36 /** |
33 * types of columns in the current table |
37 * types of columns in the current table |
34 */ |
38 */ |
35 vector<TypeId> columnTypes; |
39 vector<TypeId> columnTypes; |
36 |
40 |
37 void writeString(const string_t &stringValue, const TypeId typeId) { |
41 void writeString(const string_t &stringValue, const TypeId typeId) { |
38 for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->writeString(output, stringValue); |
42 for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->writeString(output, stringValue); |
39 throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t>(typeId)); |
43 throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t> (typeId)); |
|
44 } |
|
45 |
|
46 void writeRaw(const void* value, const type_info& typeInfo, const TypeId typeId) { |
|
47 for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->writeRaw(output, value, typeInfo); |
|
48 throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t> (typeId)); |
40 } |
49 } |
41 |
50 |
42 public: |
51 public: |
43 |
52 |
44 StreamRelationalWriter(std::ostream &output) : |
53 StreamRelationalWriter(std::ostream &output) : |
50 throw RelpipeWriterException(L"Unsupported data type: " + typeCode); |
59 throw RelpipeWriterException(L"Unsupported data type: " + typeCode); |
51 } |
60 } |
52 |
61 |
53 string_t toTypeCode(const TypeId typeId) override { |
62 string_t toTypeCode(const TypeId typeId) override { |
54 for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->getTypeCode(); |
63 for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->getTypeCode(); |
55 throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t>(typeId)); |
64 throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t> (typeId)); |
56 } |
65 } |
57 |
66 |
58 void startRelation(string_t name, std::vector<std::pair<string_t, TypeId> > attributes, boolean_t writeHeader) override { |
67 void startRelation(string_t name, std::vector<std::pair<string_t, TypeId> > attributes, boolean_t writeHeader) override { |
59 string_t tableName = name; |
68 string_t tableName = name; |
60 columnCount = attributes.size(); |
69 columnCount = attributes.size(); |
|
70 currentColumn = 0; |
61 |
71 |
62 // Write table name and column count: |
72 // Write table name and column count: |
63 integerWriter.writeValue(output, DATA_PART_START); |
73 integerWriter.writeValue(output, DATA_PART_START); |
64 stringWriter.writeValue(output, tableName); |
74 stringWriter.writeValue(output, tableName); |
65 integerWriter.writeValue(output, columnCount); |
75 integerWriter.writeValue(output, columnCount); |
74 } |
84 } |
75 |
85 |
76 // Write column types: |
86 // Write column types: |
77 for (size_t c = 0; c < columnCount; c++) { |
87 for (size_t c = 0; c < columnCount; c++) { |
78 TypeId typeId = attributes[c].second; |
88 TypeId typeId = attributes[c].second; |
79 integerWriter.writeValue(output, static_cast<integer_t>(typeId)); |
89 integerWriter.writeValue(output, static_cast<integer_t> (typeId)); |
80 columnTypes[c] = typeId; |
90 columnTypes[c] = typeId; |
81 } |
91 } |
82 |
92 |
83 } |
93 } |
84 |
94 |
85 void writeRecord(std::vector<string_t> attributes) override { |
95 void writeRecord(std::vector<string_t> attributes) override { |
86 // FIXME: check vector size |
96 // FIXME: check vector size |
|
97 // FIXME: check currentColumn == 0 |
87 for (size_t c = 0; c < columnCount; c++) { |
98 for (size_t c = 0; c < columnCount; c++) { |
88 // TODO: support multiple rows in a single method call? |
99 // TODO: do not support multiple rows in a single method call |
89 if (c % columnCount == 0) { |
100 if (c % columnCount == 0) { |
90 integerWriter.writeValue(output, DATA_PART_ROW); |
101 integerWriter.writeValue(output, DATA_PART_ROW); |
91 } |
102 } |
92 |
103 |
93 wstring stringValue = attributes[c]; |
104 wstring stringValue = attributes[c]; |
94 TypeId typeId = columnTypes[c % columnCount]; |
105 TypeId typeId = columnTypes[c % columnCount]; |
95 writeString(stringValue, typeId); |
106 writeString(stringValue, typeId); |
96 } |
107 } |
97 } |
108 } |
98 |
109 |
|
110 void writeAttribute(const void* value, const std::type_info& type) override { |
|
111 if (currentColumn == 0) integerWriter.writeValue(output, DATA_PART_ROW); |
|
112 writeRaw(value, type, columnTypes[currentColumn]); |
|
113 if (++currentColumn == columnCount) currentColumn = 0; |
|
114 } |
|
115 |
99 }; |
116 }; |
100 |
117 |
101 } |
118 } |
102 } |
119 } |