data types v_0 v0.13
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 30 Jul 2019 23:52:20 +0200
branchv_0
changeset 8 3e076cc76c89
parent 7 9119b29d1e7c
child 9 aff3a6ca254b
data types
src/SqlHandler.h
--- 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;