src/GuileHandler.h
branchv_0
changeset 10 f7f9a2553128
parent 9 65f9d6b94f5c
child 11 9603e64324bc
equal deleted inserted replaced
9:65f9d6b94f5c 10:f7f9a2553128
    57 	writer::RelationalWriter* relationalWriter;
    57 	writer::RelationalWriter* relationalWriter;
    58 
    58 
    59 	RelationConfiguration* currentRelationConfiguration = nullptr;
    59 	RelationConfiguration* currentRelationConfiguration = nullptr;
    60 	vector<AttributeMetadata> currentReaderMetadata;
    60 	vector<AttributeMetadata> currentReaderMetadata;
    61 	vector<writer::AttributeMetadata> currentWriterMetadata;
    61 	vector<writer::AttributeMetadata> currentWriterMetadata;
    62 	vector<string_t> currentRecord;
       
    63 	integer_t currentAttributeIndex = 0;
    62 	integer_t currentAttributeIndex = 0;
    64 	boolean_t includeCurrentRecord = false;
    63 	boolean_t includeCurrentRecord = false;
    65 
    64 
    66 	/**
    65 	/**
    67 	 * @param attributeName name from relational pipe
    66 	 * @param attributeName name from relational pipe
   151 
   150 
   152 	GuileHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration, const vector<string_t>& arguments) : relationalWriter(relationalWriter), configuration(configuration) {
   151 	GuileHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration, const vector<string_t>& arguments) : relationalWriter(relationalWriter), configuration(configuration) {
   153 	}
   152 	}
   154 
   153 
   155 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
   154 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
       
   155 		if (currentRelationConfiguration) evalGuileCode(currentRelationConfiguration->guileAfterRecords);
   156 		for (auto attribute : currentReaderMetadata) undefineGuileVariable(attribute.getAttributeName());
   156 		for (auto attribute : currentReaderMetadata) undefineGuileVariable(attribute.getAttributeName());
   157 		currentReaderMetadata = attributes;
   157 		currentReaderMetadata = attributes;
   158 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
   158 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
   159 		// TODO: allow structural changes during transformation
   159 		// TODO: allow structural changes during transformation
   160 		currentWriterMetadata.clear();
   160 		currentWriterMetadata.clear();
   161 		for (AttributeMetadata readerMetadata : attributes) {
   161 		for (AttributeMetadata readerMetadata : attributes) {
   162 			currentWriterMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())});
   162 			currentWriterMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())});
   163 		}
   163 		}
   164 
   164 
   165 		currentRecord.resize(attributes.size());
   165 		currentRelationConfiguration = nullptr;
   166 
       
   167 		for (int i = 0; i < configuration.relationConfigurations.size(); i++) {
   166 		for (int i = 0; i < configuration.relationConfigurations.size(); i++) {
   168 			if (regex_match(name, wregex(configuration.relationConfigurations[i].relation))) {
   167 			if (regex_match(name, wregex(configuration.relationConfigurations[i].relation))) {
   169 				currentRelationConfiguration = &configuration.relationConfigurations[i];
   168 				currentRelationConfiguration = &configuration.relationConfigurations[i];
   170 				break; // it there are multiple matches, only the first configuration is used
   169 				break; // it there are multiple matches, only the first configuration is used
   171 			}
   170 			}
   172 		}
   171 		}
   173 
   172 
   174 		relationalWriter->startRelation(name, currentWriterMetadata, true);
   173 		relationalWriter->startRelation(name, currentWriterMetadata, true);
       
   174 
       
   175 		if (currentRelationConfiguration) {
       
   176 			// TODO: better variable name, object, function?
       
   177 			defineGuileVariable(L"relpipe-relation-name", &name, typeid (name), TypeId::STRING);
       
   178 			evalGuileCode(currentRelationConfiguration->guileBeforeRecords);
       
   179 		}
   175 	}
   180 	}
   176 
   181 
   177 	void attribute(const void* value, const std::type_info& type) override {
   182 	void attribute(const void* value, const std::type_info& type) override {
   178 		if (currentRelationConfiguration) {
   183 		if (currentRelationConfiguration) {
   179 			defineGuileVariable(a2v(currentReaderMetadata[currentAttributeIndex].getAttributeName()), value, type, currentReaderMetadata[currentAttributeIndex].getTypeId());
   184 			defineGuileVariable(a2v(currentReaderMetadata[currentAttributeIndex].getAttributeName()), value, type, currentReaderMetadata[currentAttributeIndex].getTypeId());
   193 			relationalWriter->writeAttribute(value, type);
   198 			relationalWriter->writeAttribute(value, type);
   194 		}
   199 		}
   195 	}
   200 	}
   196 
   201 
   197 	void endOfPipe() {
   202 	void endOfPipe() {
   198 
   203 		if (currentRelationConfiguration) evalGuileCode(currentRelationConfiguration->guileAfterRecords);
   199 	}
   204 	}
   200 
   205 
   201 };
   206 };
   202 
   207 
   203 }
   208 }