src/GuileHandler.h
branchv_0
changeset 1 9179406ab3b3
parent 0 f36bf14d45cb
child 2 7fb4d2c70e8c
--- a/src/GuileHandler.h	Sat Jan 19 16:01:08 2019 +0100
+++ b/src/GuileHandler.h	Sun Jan 20 01:02:40 2019 +0100
@@ -26,6 +26,8 @@
 #include <codecvt>
 #include <regex>
 
+#include <libguile.h>
+
 #include <relpipe/reader/typedefs.h>
 #include <relpipe/reader/TypeId.h>
 #include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
@@ -46,6 +48,8 @@
 
 class GuileHandler : public RelationalReaderStringHadler {
 private:
+	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
+
 	shared_ptr<writer::RelationalWriter> relationalWriter;
 
 	wregex relationNameRegEx;
@@ -55,6 +59,44 @@
 	integer_t currentAttributeIndex = 0;
 	boolean_t includeCurrentRecord = false;
 	boolean_t filterCurrentRelation = false;
+	string_t guileCode;
+
+	SCM toGuileSymbol(const string_t& name) {
+		return scm_string_to_symbol(scm_from_locale_string(convertor.to_bytes(name).c_str()));
+	}
+
+	SCM toGuileString(const string_t& value) {
+		return scm_from_locale_string(convertor.to_bytes(value).c_str());
+	}
+	
+	SCM toGuileInteger(const string_t& value) {
+		return scm_from_uint64(stoul(value));
+	}
+	
+	SCM toGuileBoolean(const string_t& value) {
+		return value == L"true" ? SCM_BOOL_T : SCM_BOOL_F;
+	}
+
+	void defineGuileVariable(const string_t& name, TypeId type, const string_t& value) {
+		// TODO: RelationalReaderValueHadler?
+		switch (type) {
+			case TypeId::BOOLEAN:
+				scm_define(toGuileSymbol(name), toGuileBoolean(value));
+				break;
+			case TypeId::INTEGER:
+				scm_define(toGuileSymbol(name), toGuileInteger(value));
+				break;
+			case TypeId::STRING:
+				scm_define(toGuileSymbol(name), toGuileString(value));
+				break;
+			default:
+				throw cli::RelpipeCLIException(L"Unsupported type in defineGuileVariable()", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR);
+		}
+	}
+
+	void undefineGuileVariable(const string_t& name, TypeId type, const string_t& value) {
+		scm_define(toGuileSymbol(name), scm_make_undefined_variable()); // undefined != (define n)
+	}
 
 public:
 
@@ -62,8 +104,9 @@
 		relationalWriter.reset(writer::Factory::create(output));
 
 		// TODO: options and parser
-		if (arguments.size() == 1) {
+		if (arguments.size() == 2) {
 			relationNameRegEx = wregex(arguments[0]);
+			guileCode = arguments[1];
 		} else {
 			throw cli::RelpipeCLIException(L"Usage: relpipe-tr-guile <relationNameRegExp>", cli::CLI::EXIT_CODE_UNKNOWN_COMMAND);
 		}
@@ -74,9 +117,10 @@
 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
 		vector<writer::AttributeMetadata> writerMetadata;
 		for (AttributeMetadata readerMetadata : attributes) {
+
 			writerMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())});
 		}
-		
+
 		currentRecord.resize(attributes.size());
 		filterCurrentRelation = regex_match(name, relationNameRegEx);
 
@@ -89,6 +133,21 @@
 			currentRecord[currentAttributeIndex] = value;
 			includeCurrentRecord = false;
 
+			// TODO: remove, just a demo code
+			defineGuileVariable(L"hello", TypeId::STRING, L"world");
+			defineGuileVariable(L"a", TypeId::INTEGER, L"123");
+			defineGuileVariable(L"b", TypeId::INTEGER, L"456");
+			defineGuileVariable(L"tr", TypeId::BOOLEAN, L"true");
+			defineGuileVariable(L"fa", TypeId::BOOLEAN, L"false");
+
+			//integer_t guileResult = scm_to_uint64(scm_eval_string(toGuileString(guileCode)));
+			//std::wcerr << "result from Guile: " << guileResult << std::endl;
+			
+			includeCurrentRecord = scm_to_bool(scm_eval_string(toGuileString(guileCode)));
+			//scm_shell(0, nullptr);
+			// --------
+			
+
 			currentAttributeIndex++;
 
 			if (currentAttributeIndex > 0 && currentAttributeIndex % currentMetadata.size() == 0) {
@@ -98,6 +157,7 @@
 
 			currentAttributeIndex = currentAttributeIndex % currentMetadata.size();
 		} else {
+
 			relationalWriter->writeAttribute(value);
 		}
 	}