--- a/include/RelationalWriter.h Sun Jul 22 10:26:22 2018 +0200
+++ b/include/RelationalWriter.h Sun Jul 22 17:19:25 2018 +0200
@@ -22,6 +22,12 @@
virtual void startRelation(string_t name, std::vector<std::pair<string_t, TypeId>> attributes, boolean_t writeHeader) = 0;
virtual void writeRecord(std::vector<string_t> attributes) = 0;
+
+ // TODO: write bitmap + attribute:
+ // virtual void writeBitmap(...) = 0;
+ // virtual void writeAttribute(string_t attribute) = 0;
+
+ virtual void writeAttribute(const void* value, const std::type_info& type) = 0;
};
--- a/src/DataTypeWriter.h Sun Jul 22 10:26:22 2018 +0200
+++ b/src/DataTypeWriter.h Sun Jul 22 17:19:25 2018 +0200
@@ -1,5 +1,8 @@
#pragma once
+#include <functional>
+#include <sstream>
+
#include "DataTypeWriterBase.h"
namespace relpipe {
@@ -16,6 +19,17 @@
virtual void writeValue(std::ostream& output, const T& value) = 0;
+ void writeRaw(std::ostream& output, const void * value, const std::type_info& type) override {
+ if (type == typeid (T)) {
+ const T v = *(static_cast<const T*>(value));
+ writeValue(output, v);
+ } else {
+ wstringstream message;
+ message << L"Data type in writeRaw() does not match – got: " << type.name() << " but expected: " << typeid (T).name();
+ throw RelpipeWriterException(message.str());
+ }
+ }
+
void writeString(std::ostream& output, const string_t &stringValue) override {
writeValue(output, toValue(stringValue));
}
--- a/src/DataTypeWriterBase.h Sun Jul 22 10:26:22 2018 +0200
+++ b/src/DataTypeWriterBase.h Sun Jul 22 17:19:25 2018 +0200
@@ -32,6 +32,15 @@
virtual void writeString(std::ostream& output, const string_t &stringValue) = 0;
/**
+ * @param output output stream, should be at position where the value is to be written; the stream will not be closed not flushed after writing
+ * @param value raw pointer to the value, must exactly match data type of this writer
+ * @param type used as a safety mechanism to avoid wrong pointer interpretation;
+ * should be called in this way: writeRaw(output, valuePointer, typeid(valuePointer));
+ * if the type does not match, the RelpipeWriterException is thrown
+ */
+ virtual void writeRaw(std::ostream& output, const void * value, const std::type_info& type) = 0;
+
+ /**
* @param dataType data type code as defined in DDP L0
* @return whether this class supports conversions of this type
*/
--- a/src/StreamRelationalWriter.h Sun Jul 22 10:26:22 2018 +0200
+++ b/src/StreamRelationalWriter.h Sun Jul 22 17:19:25 2018 +0200
@@ -28,6 +28,10 @@
* count of columns in the current table
*/
integer_t columnCount;
+ /**
+ * number of column (0 = first) that will be written; after writing, the number is increased and prepared for next one
+ */
+ integer_t currentColumn;
/**
* types of columns in the current table
@@ -36,7 +40,12 @@
void writeString(const string_t &stringValue, const TypeId typeId) {
for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->writeString(output, stringValue);
- throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t>(typeId));
+ throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t> (typeId));
+ }
+
+ void writeRaw(const void* value, const type_info& typeInfo, const TypeId typeId) {
+ for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->writeRaw(output, value, typeInfo);
+ throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t> (typeId));
}
public:
@@ -52,12 +61,13 @@
string_t toTypeCode(const TypeId typeId) override {
for (DataTypeWriterBase* writer : writers) if (writer->supports(typeId)) return writer->getTypeCode();
- throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t>(typeId));
+ throw RelpipeWriterException(L"Unsupported data type: " + static_cast<integer_t> (typeId));
}
-
+
void startRelation(string_t name, std::vector<std::pair<string_t, TypeId> > attributes, boolean_t writeHeader) override {
string_t tableName = name;
columnCount = attributes.size();
+ currentColumn = 0;
// Write table name and column count:
integerWriter.writeValue(output, DATA_PART_START);
@@ -76,7 +86,7 @@
// Write column types:
for (size_t c = 0; c < columnCount; c++) {
TypeId typeId = attributes[c].second;
- integerWriter.writeValue(output, static_cast<integer_t>(typeId));
+ integerWriter.writeValue(output, static_cast<integer_t> (typeId));
columnTypes[c] = typeId;
}
@@ -84,8 +94,9 @@
void writeRecord(std::vector<string_t> attributes) override {
// FIXME: check vector size
+ // FIXME: check currentColumn == 0
for (size_t c = 0; c < columnCount; c++) {
- // TODO: support multiple rows in a single method call?
+ // TODO: do not support multiple rows in a single method call
if (c % columnCount == 0) {
integerWriter.writeValue(output, DATA_PART_ROW);
}
@@ -96,6 +107,12 @@
}
}
+ void writeAttribute(const void* value, const std::type_info& type) override {
+ if (currentColumn == 0) integerWriter.writeValue(output, DATA_PART_ROW);
+ writeRaw(value, type, columnTypes[currentColumn]);
+ if (++currentColumn == columnCount) currentColumn = 0;
+ }
+
};
}