--- a/src/SqlHandler.h Tue Jul 30 23:04:33 2019 +0200
+++ b/src/SqlHandler.h Tue Jul 30 23:52:20 2019 +0200
@@ -24,12 +24,13 @@
#include <locale>
#include <codecvt>
#include <unistd.h>
+#include <cassert>
#include <sqlite3.h>
#include <relpipe/reader/typedefs.h>
#include <relpipe/reader/TypeId.h>
-#include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
+#include <relpipe/reader/handlers/RelationalReaderValueHandler.h>
#include <relpipe/reader/handlers/AttributeMetadata.h>
#include <relpipe/writer/Factory.h>
@@ -59,6 +60,16 @@
sqlite3_finalize(stmt);
}
+ void setBoolean(int parameterIndex, relpipe::reader::boolean_t value) {
+ int result = sqlite3_bind_int(stmt, parameterIndex, value);
+ if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
+ }
+
+ void setInteger(int parameterIndex, relpipe::reader::integer_t value) {
+ int result = sqlite3_bind_int64(stmt, parameterIndex, value);
+ if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
+ }
+
void setString(int parameterIndex, std::string value) {
int result = sqlite3_bind_text(stmt, parameterIndex, value.c_str(), -1, SQLITE_TRANSIENT);
if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
@@ -127,7 +138,7 @@
};
-class SqlHandler : public RelationalReaderStringHandler {
+class SqlHandler : public RelationalReaderValueHandler {
private:
Configuration configuration;
writer::RelationalWriter* relationalWriter;
@@ -159,7 +170,7 @@
}
relpipe::writer::string_t toSQLType(relpipe::reader::TypeId typeId) {
- if (typeId == relpipe::reader::TypeId::BOOLEAN) return L"boolean";
+ if (typeId == relpipe::reader::TypeId::BOOLEAN) return L"integer"; // TODO: map selected values back to booleans or allow optional storage as string
else if (typeId == relpipe::reader::TypeId::INTEGER) return L"integer";
else return L"text";
}
@@ -214,11 +225,37 @@
currentInsert.reset(connection->prepareStatement(convertor.to_bytes(sql.str()).c_str()));
}
- void attribute(const string_t& value) override {
+ void attribute(const void* value, const std::type_info& typeInfo) override {
+ relpipe::reader::TypeId type = currentReaderMetadata[currentAttributeIndex].getTypeId();
currentAttributeIndex++;
- if (currentAttributeIndex % currentReaderMetadata.size()) {
- currentInsert->setString(currentAttributeIndex, convertor.to_bytes(value).c_str());
- } else {
+
+ switch (type) {
+ case relpipe::reader::TypeId::BOOLEAN:
+ {
+ assert(typeInfo == typeid (boolean_t));
+ auto* typedValue = static_cast<const boolean_t*> (value);
+ currentInsert->setBoolean(currentAttributeIndex, *typedValue);
+ break;
+ }
+ case relpipe::reader::TypeId::INTEGER:
+ {
+ assert(typeInfo == typeid (integer_t));
+ auto* typedValue = static_cast<const integer_t*> (value);
+ currentInsert->setInteger(currentAttributeIndex, *typedValue);
+ break;
+ }
+ case relpipe::reader::TypeId::STRING:
+ {
+ assert(typeInfo == typeid (string_t));
+ auto* typedValue = static_cast<const string_t*> (value);
+ currentInsert->setString(currentAttributeIndex, convertor.to_bytes(*typedValue).c_str());
+ break;
+ }
+ default:
+ throw SqlException(L"Unsupported type in attribute()");
+ }
+
+ if (currentAttributeIndex % currentReaderMetadata.size() == 0) {
currentInsert->next();
currentInsert->reset();
currentAttributeIndex = 0;