diff -r f36bf14d45cb -r 9179406ab3b3 src/GuileHandler.h --- 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 #include +#include + #include #include #include @@ -46,6 +48,8 @@ class GuileHandler : public RelationalReaderStringHadler { private: + std::wstring_convert> convertor; // TODO: support also other encodings. + shared_ptr 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 ", 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 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); } }