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); |