src/GuileHandler.h
branchv_0
changeset 11 9603e64324bc
parent 10 f7f9a2553128
child 12 7977c1bdba1f
equal deleted inserted replaced
10:f7f9a2553128 11:9603e64324bc
   112 
   112 
   113 	void defineGuileVariable(const string_t& name, const void* value, const std::type_info& typeInfo, TypeId type) {
   113 	void defineGuileVariable(const string_t& name, const void* value, const std::type_info& typeInfo, TypeId type) {
   114 		scm_define(toGuileSymbol(name), toGuileValue(value, typeInfo, type));
   114 		scm_define(toGuileSymbol(name), toGuileValue(value, typeInfo, type));
   115 	}
   115 	}
   116 
   116 
       
   117 	/**
       
   118 	 * TODO: use a common method
       
   119 	 */
       
   120 	bool parseBoolean(const string_t& value) {
       
   121 		if (value == L"true") return true;
       
   122 		else if (value == L"false") return false;
       
   123 		else throw relpipe::cli::RelpipeCLIException(L"Unable to parse boolean value: " + value + L" (expecting true or false)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
       
   124 	}
       
   125 
       
   126 	void defineGuileVariable(const DefinitionRecipe& definition) {
       
   127 		switch (relationalWriter->toTypeId(definition.type)) {
       
   128 			case writer::TypeId::BOOLEAN:
       
   129 			{
       
   130 				boolean_t value = parseBoolean(definition.value);
       
   131 				defineGuileVariable(definition.name, &value, typeid (value), TypeId::BOOLEAN);
       
   132 				break;
       
   133 			}
       
   134 			case writer::TypeId::INTEGER:
       
   135 			{
       
   136 				integer_t value = stoul(definition.value);
       
   137 				defineGuileVariable(definition.name, &value, typeid (value), TypeId::INTEGER);
       
   138 				break;
       
   139 			}
       
   140 			case writer::TypeId::STRING:
       
   141 			{
       
   142 				defineGuileVariable(definition.name, &definition.value, typeid (definition.value), TypeId::STRING);
       
   143 				break;
       
   144 			}
       
   145 			default:
       
   146 				throw cli::RelpipeCLIException(L"Unsupported type in defineGuileVariable(): " + definition.type, cli::CLI::EXIT_CODE_UNEXPECTED_ERROR);
       
   147 		}
       
   148 	}
       
   149 
   117 	void undefineGuileVariable(const string_t& name) {
   150 	void undefineGuileVariable(const string_t& name) {
   118 		scm_define(toGuileSymbol(name), scm_make_undefined_variable()); // undefined != (define n)
   151 		scm_define(toGuileSymbol(name), scm_make_undefined_variable()); // undefined != (define n)
   119 		// TODO: or use: scm_variable_unset_x() ?
   152 		// TODO: or use: scm_variable_unset_x() ?
   120 	}
   153 	}
   121 
   154 
   150 
   183 
   151 	GuileHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration, const vector<string_t>& arguments) : relationalWriter(relationalWriter), configuration(configuration) {
   184 	GuileHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration, const vector<string_t>& arguments) : relationalWriter(relationalWriter), configuration(configuration) {
   152 	}
   185 	}
   153 
   186 
   154 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
   187 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
   155 		if (currentRelationConfiguration) evalGuileCode(currentRelationConfiguration->guileAfterRecords);
   188 		if (currentRelationConfiguration) {
       
   189 			evalGuileCode(currentRelationConfiguration->guileAfterRecords);
       
   190 			for (DefinitionRecipe definition : currentRelationConfiguration->definitions) undefineGuileVariable(definition.name);
       
   191 		}
   156 		for (auto attribute : currentReaderMetadata) undefineGuileVariable(attribute.getAttributeName());
   192 		for (auto attribute : currentReaderMetadata) undefineGuileVariable(attribute.getAttributeName());
   157 		currentReaderMetadata = attributes;
   193 		currentReaderMetadata = attributes;
   158 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
   194 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
   159 		// TODO: allow structural changes during transformation
   195 		// TODO: allow structural changes during transformation
   160 		currentWriterMetadata.clear();
   196 		currentWriterMetadata.clear();
   164 
   200 
   165 		currentRelationConfiguration = nullptr;
   201 		currentRelationConfiguration = nullptr;
   166 		for (int i = 0; i < configuration.relationConfigurations.size(); i++) {
   202 		for (int i = 0; i < configuration.relationConfigurations.size(); i++) {
   167 			if (regex_match(name, wregex(configuration.relationConfigurations[i].relation))) {
   203 			if (regex_match(name, wregex(configuration.relationConfigurations[i].relation))) {
   168 				currentRelationConfiguration = &configuration.relationConfigurations[i];
   204 				currentRelationConfiguration = &configuration.relationConfigurations[i];
       
   205 				for (DefinitionRecipe definition : currentRelationConfiguration->definitions) defineGuileVariable(definition);
   169 				break; // it there are multiple matches, only the first configuration is used
   206 				break; // it there are multiple matches, only the first configuration is used
   170 			}
   207 			}
   171 		}
   208 		}
   172 
   209 
   173 		relationalWriter->startRelation(name, currentWriterMetadata, true);
   210 		relationalWriter->startRelation(name, currentWriterMetadata, true);